Python_爬虫_多线程入门_一蓑烟雨任平生

Python爬虫入门教程 14-100 All IT eBooks多线程爬取 python3入门教程,All It eBooks网站多线程爬取,可以快速的通过使用requests_html 和 queue模块爬取你想要的PDF书籍 阅读详情


前言

使用这篇Dome的代码可以入门多线程


一、基础知识

1.python多线程 生产者与消费者模式官方文档:17.1. threading — 基于线程的并行点这里
两个案例参考:用Python多线程实现生产者消费者模式点这里
python-多线程3-生产者消费者点这里

2.@property 装饰器既要保护类的封装特性,又要让开发者可以使用“对象.属性”的方式操作操作类属性,除了使用 property() 函数,Python 还提供了 @property 装饰器。
通过 @property 装饰器,可以直接通过方法名来访问方法,不需要在方法名后添加一对“()”小括号。
参考:点这里

3.@staticmethod 静态方法@staticmethod 静态方法只是名义上归属类管理,但是不能使用类变量和实例变量,是类的工具包 放在函数前(该函数不传入self或者cls),所以不能访问类属性和实例属性。
参考:Python进阶-----静态方法(@staticmethod)点这里
Python staticmethod() 函数点这里

4.Queue 队列queue 模块实现多生产者,多消费者队列。当信息必须安全的在多线程之间交换时,它在线程编程中是特别有用的。
此模块中的 Queue 类实现了所有锁定需求的语义。Queue.put(item, block=True, timeout=None) 将 item 放入队列。如果可选参数 block 是 true 并且 timeout 是 None (默认),则在必要时阻塞至有空闲插槽可用。如果 timeout 是个正数,将最多阻塞 timeout 秒,如果在这段时间没有可用的空闲插槽,将引发 Full 异常。
反之 (block 是 false),如果空闲插槽立即可用,则把 item 放入队列,否则引发 Full 异常 ( 在这种情况下,timeout 将被忽略)。
参考:17.7. queue — 一个同步的队列类点这里 还是推荐和尝试去阅读官方文档,慢慢理解和实践!

二、Demo代码

# BillWang 博闻 采集
# 微信:15838129129
# -*- coding: UTF-8 -*-
import requests
import os, random, re
from lxml import etree
import threading
from queue import Queue


class Httprequest(object):
    ua_list = [
        'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.163 Safari/535.1',
        'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36Chrome 17.0',
        'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11',
        'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20100101 Firefox/6.0Firefox 4.0.1',
        'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0.1) Gecko/20100101 Firefox/4.0.1',
        'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50',
        'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50',
        'Opera/9.80 (Windows NT 6.1; U; en) Presto/2.8.131 Version/11.11',
    ]

    @property  # 把方法变成属性的装饰器
    def random_headers(self):
        return {
            'User-Agent': random.choice(self.ua_list)
        }


# 生产者模式
class Procuder(threading.Thread, Httprequest):
    def __init__(self, page_queue, img_queue, *args, **kwargs):
        super(Procuder, self).__init__(*args, **kwargs)
        self.url = "http://www.billwang.net/html/blogs/"
        self.page_queue = page_queue
        self.img_queue = img_queue

    def run(self):
        while True:
            if self.page_queue.empty():
                break
            url = self.page_queue.get()
            self.get_list(url)

    def get_list(self, url):
        print(f">>> 正在爬取列表页 {url}")
        html = requests.get(url, headers=self.random_headers, timeout=5).content.decode('utf-8')
        req = etree.HTML(html)
        hrefs = req.xpath('//div[@class="txtbox"]/a/@href')
        for href in hrefs:
            href = f'{self.url.split("/html")[0]}{href}'
            self.get_content(href)

    def get_content(self, url):
        print(f">>> 正在爬取详情页 {url}")
        html = requests.get(url, headers=self.random_headers, timeout=5).content.decode('utf-8')
        req = etree.HTML(html)
        title = req.xpath('//div[@class="detail-con"]/h1[@class="title"]/text()')[0]
        h1 = self.validate_title(title)
        content = req.xpath('//div[@class="content"]//text()')
        content = self.deal_content(content)
        content_req = req.xpath('//div[@class="content"]')[0]
        imgs = content_req.xpath('*//img/@src')
        data = (h1, content, imgs)
        print(data)
        self.img_queue.put(data)

    @staticmethod
    def validate_title(title):
        pattern = r"[\/\\\:\*\?\"\<\>\|]"
        new_title = re.sub(pattern, "_", title)  # 替换为下划线
        return new_title

    @staticmethod  # @staticmethod 静态方法只是名义上归属类管理,但是不能使用类变量和实例变量,是类的工具包放在函数前(该函数不传入self或者cls),所以不能访问类属性和实例属性
    def deal_content(content):
        content.remove('\n        ')
        content.remove('        ')
        content = ' '.join(content)
        content = content.replace('免责声明:本站目的在于分享更多信息,不代表本站的观点和立场,版权归原作者所有。若有侵权或异议请联系我们删除。', '')
        return content


# 消费者模式
class Consumer(threading.Thread, Httprequest):
    def __init__(self, page_queue, img_queue, *args, **kwargs):
        super(Consumer, self).__init__(*args, **kwargs)
        self.page_queue = page_queue
        self.img_queue = img_queue
        self.path = f'billw/'

    def save_content(self, h1, content, path):
        os.makedirs(self.path, exist_ok=True)  # 创建文件夹
        print(f">>> 开始保存 {h1}文本内容")
        text = '%s%s%s' % (h1, '\n', content)
        with open(f'{path}{h1}.txt', 'w', encoding='utf-8') as f:
            f.write(text)
        print(">>> 保存成功!")

    def save_imgs(self, imgs, path):
        i = 1
        for img in imgs:
            img_url = img
            img_name = f'{i}{os.path.splitext(img)[-1]}'
            img_path = f'{path}{img_name}'
            self.save_img(img_url, img_name, img_path)
            i = i + 1

    def save_img(self, img_url, img_name, img_path):
        print(f">>> 开始保存 {img_name} 图片")
        r = requests.get(img_url, headers=self.random_headers, timeout=5)
        with open(img_path, 'wb') as f:
            f.write(r.content)
        print(f">>> 保存 {img_name} 图片成功")

    def run(self):
        while True:
            if self.page_queue.empty() and self.img_queue.empty():
                break
            data = self.img_queue.get()
            h1 = data[0]
            content = data[1]
            imgs = data[2]
            path = f'billw/{h1}/'
            os.makedirs(path, exist_ok=True)  # 创建文件夹
            self.save_content(h1, content, path)
            self.save_imgs(imgs, path)


def main():
    page_queue = Queue(100)
    img_queue = Queue(10000)
    for i in range(1, 21):
        url = "http://www.billwang.net/html/blogs/%d/" % i
        print(f'>>> 正在爬取 第{i}页 列表页,链接:{url} ...')
        page_queue.put(url)

    for x in range(2):
        t = Procuder(page_queue, img_queue)
        t.start()

    for x in range(8):
        t = Consumer(page_queue, img_queue)
        t.start()


if __name__ == "__main__":
    main()


总结

这里进行自己学习多线程的开始
在这里插入图片描述

python爬虫demo 立即下载

相关推荐

Python-新手用来练手的Python小Demo合集

新手用来练手的Python小Demo合集

Python方法:@staticmethod和@classmethod

在常用的Python方法中,我们调用类的方法,每次都需要进行实例化,然后用实例化.方法进行调用。Python方法@staticmethod和@classmethod,可以被类直接调用,也可以被所有实例化对象共享。只要在某个方法前面加上@staticmethod或@classmethod就可以了,该方法通过调用staticmethod并且这样子还,把某些应该属于某个类的函数给放到那个类里去,同时。

Python,数据分析,机器学习,深度学习 7494

爬虫工具BeautifulSoup的入门级Demo

入门级的爬虫代码,5分钟马上会用。超级简单,不用再看那么多的资料了。

python-爬虫

1、好的参考网址 (1)https://www.cnblogs.com/h3zh1/p/12548946.html 这个地址讲解的都是比较基础的东西,对理解爬虫很有帮助 (2)https://www.52pojie.cn/forum.php?mod=viewthread&tid=1179932 一个爬虫的经典例子不错 (3)https://blog.youkuaiyun.com/pdstar/article/details/79383090 讲解为什么需要模拟浏览器进行爬取网页 (4)https://my.os

lhh_qrsly的博客 515

二、频率调制光谱(FMS)技术——error信号的数学模型及其他推论

一些推论。

qq_41111336的博客 1604

Ubuntu18.04环境搭建与疑难解析:从零复现YOLO-6D姿态估计算法

本文详细介绍了在Ubuntu18.04环境下从零开始复现YOLO-6D姿态估计算法的完整流程,包括系统配置、Conda环境搭建、PyTorch安装、依赖项管理、源代码获取、数据集准备以及训练验证过程。针对Singleshotpose算法的特殊需求,提供了详细的疑难解析和性能优化技巧,帮助开发者高效完成算法复现和应用部署。

weixin_30369041的博客 452

简单的Python爬虫demo

先说一下这个常量类的作用,一开始我的设想是想参考Java项目那样可以把常量单独放到一个文件中,数据库连接单独放到一个文件中,sql语句单独放到一个文件中。这里额外上一个代码 historyData.py 这个代码是我用来抓取历史的,和主程序的区别就是 主程序是每次只抓取最新的一条数据,该程序可通过URL中的参数指定抓取一批数据。关于代码的解释都直接在代码中用注释进行了说明,但后续在部署中发现,代码中虽然是注释的部分或者打印的部分,只有存在中文或者中文字符就可能报字符编码的问题,尤其是使用。

郝南过的博客 1335

基于PDF文档结构的数字隐写

PDF隐写

xiongshivigor的博客 1426

python多线程执行类中的静态方法

在python 中如果通过多线程的方式执行某个方法很简单,只需要把同步函数的第一个参数为该函数对象即可。但是如果函数对象是某个类的静态方法,这时候如果直接使用类的该函数对象会报错。此时需要构造一个代理的方法来实现。 如:上一个博文中的统计目录大小的静态类方法,如果想要查询多目录的空间大小,并且做成多线程个的方式。可采用下面的方法: def dir_size_proxy(cls_instan...

weixin_30245867的博客 777

从理论到实践:利用FilterSolutions高效设计7阶椭圆低通滤波器

本文详细介绍了如何利用FilterSolutions软件高效设计7阶椭圆低通滤波器。文章从理论入手,对比了巴特沃斯、切比雪夫等经典滤波器特性,阐述了在要求高衰减陡度(如62dB抑制)和严格通带波纹(0.2dB)时,椭圆滤波器是最优选择。通过分步实战教程,指导读者完成从软件参数设置、性能验证到实际电路布局与调试的全过程,助力射频与高速数字信号处理工程师将理论转化为可靠设计。

jupi8的博客 558

MATLAB基础应用精讲-【数模应用】数字预失真(DPD)(附MATLAB代码实现)

近年来,随着无线通信技术的发展,高功率放大器 (PA) 在提高信号传输功率的同时,也带来了非线性失真问题。PA的非线性失真会造成信号频谱扩展、功率下降、邻道干扰等问题,严重影响系统性能。为了克服PA的非线性失真,数字预失真 (DPD) 技术应运而生。DPD技术通过在发射机中引入一个非线性模块,对信号进行预失真处理,从而补偿PA的非线性失真。

qq_36130719的博客 895

python的@classmethod和@staticmethod

本文是对StackOverflow上的一篇高赞回答的不完全翻译,原文链接:Meaning of @classmethod and @staticmethod for beginner        Python面向对象编程中,类中定义的方法可以是 @classmethod 装饰的类方法,也可以是 @staticmethod 装饰的静态方法,用的最多的还是不带装饰器的实例方法。为方便,在下文中

crazyliu的博客 4676

S7-200SMART通过表格指令实现模拟量信号滑动平均值滤波的具体方法

S7-200SMART通过表格指令实现模拟量信号滑动平均值滤波的具体方法

Robot_PLC_HMI_Automation 6724

Python图片下载器(单线程PK多线程)_一蓑烟雨任平生

文章目录前言一、有编程基础的看这个二、没编程基础的看这个总结 前言 最近电脑总是弹出少儿不宜网站,关了,过两天又出来,我真的受不了了,那就盘它好了,本博客分两部分,针对小白一份源码,针对不会编程的人群一份exe,双击就可以了 一、有编程基础的看这个 # 爬取妹子图全网妹子图片,可以选择爬取年份,自动分类保存 import requests, os, time import urllib3 # 这个纯粹防止warning提示,没啥作用 import easygui urllib3.disable_war

Jaeger_Java的博客 1921

看懂 SAP S/4HANA 产品主数据里的 GTIN:一串号码背后的全球商品识别与业务协同

SAP S/4HANA中的GTIN管理是企业供应链运营的关键环节。本文深入解析GTIN的业务内涵及其在SAP系统中的实现方式:1) GTIN是全球通用的商品标识码,不同于企业内部物料编码;2) SAP主数据中GTIN与计量单位强绑定,需为不同包装层级维护独立GTIN;3) 同一产品可能因渠道、供应商差异存在多个GTIN;4) GTIN贯穿零售POS、仓储管理、EDI订单等核心业务流程;5) 通过典型案例说明错误维护GTIN将导致收银异常、仓库作业低效等运营问题。文章强调GTIN管理需结合包装层级、计量单位等

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1431

uniapp [安卓苹果App端] - 详细实现下载文件保存到用户手机本地,指定文件存储位置路径及文件夹名称下载并保存,Uniapp app端将文件下载保存并储存到指定目录(手机系统存储空间权限检测)

uni-app,安卓Android,苹果ios,安卓app端,苹果App端,uniapp苹果安卓app,app端下载文件,移动端文件下载,并保存到手机本地存储空间,uniapp下载文件保存到手机本地,iOS下载文件怎么保存,系统读写存储空间权限,下载文件到本地详细流程及源代码,保存自定义目录,uniapp,实现下载文件并保存到本地,文件后缀,如何指定手机的存放目录路径url,点击下载文档到手机中并提示存储位置,如何在uniapp中实现文件下载功能,uniApp文件下载,怎么指定文件保存目录,下载报错,没反应

🏆 前端领域优质创作者 1万+

python多线程方法总结

python多线程方法

u010562884的博客 2977

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

python static 的用法_Python,你真的会使用 staticmethod 和 classmethod 吗?

1. 场景前几天,有一个小伙伴过来问我,Python 中的 @staticmethod、@classmethod、self、cls 分别代表什么意思,自己平时光顾着用,不知道具体的含义?事实上,由于 Python 语言的灵活性,这部分内容在日常编码过程中,很容易被忽略掉本篇文章将和大家一起聊聊这几个小知识点2.@staticmethod装饰器 @staticmethod 修饰的方法称为:静态方法,...

weixin_42352453的博客 941

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

python掷骰子实验_Python基础(十二) 模拟掷骰子demo

模拟掷骰子1.0'''模拟掷骰子1.0'''import randomdef roll_dice():"""模拟掷骰子"""roll = random.randint(1, 6)return rolldef main():"""主函数"""total_times = 10000# 初始化列表 [0, 0, 0, 0, 0, 0]result_list = [0] * 6for i in range...

weixin_34871733的博客 731

python-基础运用小demo

基础运用小demo一、基础运算二、判断质数三、九九乘法表 一、基础运算 这里我们利用一个基础运算,实现数字的倒输出。 实现的过程: 1、我们先使用input函数键盘录入一个想要倒数输出的整数 2、之后我们定义一个while循环和一个值为0的变量i 3、第一次循环,aa % 10是为了 取出 数字的最后一位 4、aa=aa//10是为了让数字 去除 最后一位 5、第二次循环时我们在 取出 最后一位的时候加上刚才最后一位的10倍实现开始倒序 6、当数字已经小于0时,数字倒序输出完成,循环终止,所以判断

weixin_49006942的博客 377

Python基础知识总结

Python基础知识总结 基础中的基础 列表、元组(tuple)、字典、字符串 变量和引用 函数 面向对象 基础中的基础 解释型语言和编译型语言差距; Python概述 解释器执行原理 which python3可以查看python3的位置(linux下); 交互式环境中使用exit()或者ctrl+D退出; 9 // 2表示取结果的整数,乘方使用**; 乘法可以用在 字符串中 也就...

zxzxin的博客~ 2万+

low版爬虫脚本,Python简单图片爬虫案例

现在很多网站都是异步加载的方式加载数据,大部分都是json数据,如果不知道数据的传递过程,一些参数理不清头绪的话,又想要获取数据,那就比较难搞了,尤其是对于本渣渣级选手而言。 ...

二爷记 895

python3读写excel文件_python 入门 第三版Python读写/追加excel文件Demo分享

三个工具包python操作excel的三个工具包如下,注意,只能操作.xls,不能操作.xlsx。• xlrd: 对excel进行读相关操作学习电脑网从Python读写/追加excel文件Demo分享分析来看,对Python读写/追加excel文件Demo分享的结果。• xlwt: 对excel进行写相关操作• xlutils: 对excel读写操作的整合这三个工具包都可以直接使用pip进行下载:...

weixin_39552179的博客 137

小甲鱼零基础入门学习python笔记

小甲鱼老师零基础入门学习Python全套资料百度云(包括小甲鱼零基础入门学习Python全套视频+全套源码+全套PPT课件+全套课后题及Python常用工具包链接、电子书籍等)请往我的资源(https://download.youkuaiyun.com/download/qq_32809093/11528609)查看 000 愉快的开始 python跨平台。 应用范围:操作系统、WEB、3D动画、企业应用...

qq_32809093的博客 14万+

Python编程:从入门到实践-项目2-数据可视化-matplotlib.pyplot-Demo

前记:由于python大二在看,半途写了一些入门代码,不过很快忘了,中间上课偶尔又在看一本叫什么 Python-cook book的书,就一直没有丢,但是又一直没进化这门语言的能力;python 就是适合处理数据,他的数据结构真的很简单,而且对于分析者用法透明;越说越激动了,开始调库吧!安装就不用说了;这此就是一个简单的代码,调库就是这么简单粗暴,实现以下的可视化,生成  x的平方曲线,后面代码你...

Tianjack的博客 804

Python爬虫_宅男福利?妹纸勿点__一蓑烟雨任平生

咳咳直接上代码 #!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2020/12/15 19:10 # @Author : huni # @File : 图库大全1000.py # @Software: PyCharm import requests from lxml import etree import os if __name__ == '__main__': headers = { 'User-A

Jaeger_Java的博客 1万+
上一篇: Python_selenium_自动化_一蓑烟雨任平生
下一篇: Python selenium自动化脚本右键保存图片_一蓑烟雨任平生
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值