接着之前的MonkeyLei:Python-爬取页面内容(涉及urllib、requests、UserAgent、Json等) 继续练习下多线程,线程池模拟..

我想这样:

1. 创建一个线程池,线程池数量可以定为初始化16大小(如果无可用线程,则再次分配16个线程加入到线程池 - 目前线程编号有重复)

2. 然后url列表装载到一个队列Queue里面

3. 接下来遍历url列表数量(无需获取url,只是为了启动一个线程来处理url),同时启动一个线程(该线程会从队列里面去获取url进行爬取)

4(attention). 然后主线程等待子线程运行完毕(过程中加入了运行线程是否活着的判断,如果运行了就不用join了)

5(attention). 网络请求添加了超时请求,github模拟会比较慢,懒得等

So,看代码

thread_pool.py

#!/usr/bin/python3
# -*- coding: UTF-8 -*-
# 文件名:thread_pool.pyfrom threading import Thread
from queue import Queue
import time as Time
from urllib import requesttread_pool_len = 16
threads_pool = []
running_thread = []
url_list = ['http://www.baidu.com','https://github.com/FanChael/DocPro','http://www.baidu.com','http://www.baidu.com','http://www.baidu.com','https://github.com/FanChael/DocPro','http://www.baidu.com','http://www.baidu.com','http://www.baidu.com','http://www.baidu.com','http://www.baidu.com','https://github.com/FanChael','https://github.com/FanChael',
]# url列表长度
url_len = len(url_list)
# 创建队列并初始化
queue = Queue(url_len)
for url in url_list:queue.put(url)# 伪装浏览器
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36',
}# 自定义线程
class my_thread(Thread):def __init__(self):Thread.__init__(self)def run(self):if not queue.empty():print(self.getName(), '运行中')data = ''try:req = request.Request(queue.get(), None, headers)with request.urlopen(req, timeout=5) as uf:while True:data_temp = uf.read(1024)if not data_temp:breakdata += data_temp.decode('utf-8', 'ignore')# print('线程', self.getName(), '获取数据=', data)except Exception as err:print(self.getName(), str(err))else:pass# 初始化线程池
def init_thread(count):thread_count = len(threads_pool)for i in range(thread_count, count):thead = my_thread()thead.setName('第' + str(i) + '号线程')threads_pool.append(thead)# 获取可用线程 - 优化思路: 每次都遍历一遍效率低,可以封装对象,设置标示位,执行结束后改变标志位状态;但这样还是要循环一遍;此时取到一定数量或者快到头了,然后再从头遍历
def get_available():for c_thread in threads_pool:if not c_thread.isAlive():threads_pool.remove(c_thread)return c_thread# 扩容线程init_thread(tread_pool_len)return get_available()if __name__ == '__main__':# 初始化线程池init_thread(tread_pool_len)# 启动时间start_time = Time.time()# 启动线程去从队列获取url执行请求for i in range(url_len):a_thread = get_available()if a_thread:running_thread.append(a_thread)a_thread.start()# 主线程等所有子线程运行完毕for t in running_thread:if t.isAlive():t.join()# 结束时间end_time = Time.time()print(len(running_thread), '个线程, ', '运行时间: ', end_time - start_time, '秒')print('空余线程数: ', len(threads_pool))

Result :

D:PycharmProjectspython_studyvenv3.xScriptspython.exe D:/PycharmProjects/python_study/protest/thread_pool.py
第0号线程 运行中
第1号线程 运行中
第2号线程 运行中
第3号线程 运行中
第4号线程 运行中
第5号线程 运行中
第6号线程 运行中
第7号线程 运行中
第8号线程 运行中
第9号线程 运行中
第0号线程 运行中
第1号线程 运行中
第2号线程 运行中
第1号线程 <urlopen error timed out>
第2号线程 The read operation timed out
13 个线程,  运行时间:  20.04409170150757 秒
空余线程数:  7Process finished with exit code 0

工程练习地址: https://gitee.com/heyclock/doc/tree/master/Python/python_study

补充....这个地方我还会去看哈主流的线程池爬虫方案(其中官方线程池的用法参考: python线程池 ThreadPoolExecutor 的用法及实战),然后学习下,然后补充

threadpoolexecutor_practice.py

#!/usr/bin/python3
# -*- coding: UTF-8 -*-
# 文件名:threadpoolexecutor_practice.pyfrom concurrent.futures import ThreadPoolExecutor, wait, FIRST_COMPLETED, ALL_COMPLETED, as_completed
from urllib import request# 伪装浏览器
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36',
}url_list = ['http://www.baidu.com','https://github.com/FanChael/DocPro','http://www.baidu.com','http://www.baidu.com','http://www.baidu.com','https://github.com/FanChael/DocPro','http://www.baidu.com','http://www.baidu.com','http://www.baidu.com','http://www.baidu.com','http://www.baidu.com','https://github.com/FanChael','https://github.com/FanChael',
]def spider(url_path):data_html = ''try:req = request.Request(url_path, None, headers)# 爬到内容不对的还需要结合selenium等获取动态js内容with request.urlopen(req, timeout=5) as uf:while True:data_temp = uf.read(1024)if not data_temp:breakdata_html += data_temp.decode('utf-8', 'ignore')# 爬到的数据可以本地或者数据库 - 总之进行一系列后续处理print(url_path, " 完成")except Exception as err:print(str(err))else:passreturn data_html# 创建一个最大容量为1的线程
executor = ThreadPoolExecutor(max_workers=16)if __name__ == '__main__':tasks = []# 执行蜘蛛并加入执行列表for url in url_list:# 执行函数,并传入参数task = executor.submit(spider, url)tasks.append(task)# 等待方式1: 结束# wait(tasks, return_when=ALL_COMPLETED)# 等待方式2:结束for future in as_completed(tasks):# spider方法无返回,则返回为Nonedata = future.result()print(f"main:{data[0:10]}")# 等待方式3: 结束 - 替代submit并伴随等待!# for data in executor.map(spider, url_list):#     print(data)print('结束啦')

官方的线程池,更简单一些,别人都做好了处理线程的管理。其实点击进去看看源码,大概也知道,也有类似的扩容处理,然后调用封装,任务也都是放到的队列里面的。比如下面一段源码:

线程池练习, 更好的封装,比如 (你自己初步实现,然后可以包装起来独立模块,外部提供参数运行)https://blog.csdn.net/Key_book/article/details/80258022

OK,先酱紫...下一步数据库连接,正则匹配学哈。。差不多公司项目就可以看看了....具体其他的再深入...

附录:https://blog.csdn.net/Key_book/article/details/80258022 - python爬虫之urllib,伪装,超时设置,异常处理

pool python 传参数_Python-爬虫-多线程、线程池模拟(urllib、requests、UserAgent、超时等)...相关推荐

  1. python post 参数_python爬虫——requests库使用代理

    在看这篇文章之前,需要大家掌握的知识技能: python基础 html基础 http状态码 让我们看看这篇文章中有哪些知识点: get方法 post方法 header参数,模拟用户 data参数,提交 ...

  2. 多线程线程池的实现java_如何在Java中实现线程池

    多线程线程池的实现java 线程是独立程序的执行路径. 在java中,每个线程都扩展java.lang.Thread类或实现java.lang.Runnable. 多线程是指在一个任务中同时执行两个或 ...

  3. 线程池传递对象参数_一次线程池参数错误引起的线上故障

    在JAVA里,我们通常会把没有前后依赖关系的逻辑操作扔到多个线程里并行执行,以提高代码运行效率. 同时,我们一般也不会单独显式创建线程,而是通过线程池设置线程.使用线程池的好处是减少在创建和销毁线程上 ...

  4. 多线程线程池的基本创建,使用方法

    import java.util.concurrent.*;/*** 多线程线程池的基本创建,使用方法** @author silence*/ public class Silence {public ...

  5. python爬虫代理服务器_Python爬虫多线程抓取代理服务器

    Python作为一门功能强大的脚本语言来说,经常被用来写爬虫程序,下面是Python爬虫多线程抓取代理服务器 首先通过谷歌把包含代理服务器地址的网页查出来,我选择从 http://www.88181. ...

  6. python异步线程算法应用_Python多线程----线程池以及线程实现异步任务

    了解异步编程 楼主在工作中遇到了以下问题,开发接口爬取数据代码完成之后要写入redis缓存,但是在写入缓存的过程花费2-3s,进行这样就大大影响了接口的性能,于是想到了使用异步存储. 传统的同步编程是 ...

  7. python爬取京东手机参数_python爬虫——分页爬取京东商城商品信息(手机为例)...

    1.最近刚开始学习python   写了个爬虫练习,感觉主要是得会用F12查询网站结构代码.还涉及到反爬虫,每个网站都不一样,拿到的解析出的json数据格式也不同.得有些Web知识的基础才行. htt ...

  8. python解析原理_python爬虫原理

    简单来说互联网是由一个个站点和网络设备组成的大网,我们通过浏览器访问站点,站点把HTML.JS.CSS代码返回给浏览器,这些代码经过浏览器解析.渲染,将丰富多彩的网页呈现我们眼前: 一.爬虫是什么? ...

  9. python异步爬虫之线程池

    单线程不足之处 当对多个url发送请求时,只有请求完第一个url才会接着请求第二个url(requests是一个阻塞的操作),比如下载图片,这种一个个执行的方式称为单线程.其存在等待的时间,这样效率是 ...

最新文章

  1. Fibonacii数列,兔子问题
  2. JSP九大内置对象...
  3. mongoose 批量修改字段_记一次脚本批量修改数据库字符集所埋下的一个坑及解决思路...
  4. where is ConstraintViolationException raised
  5. 最新解决ora-01034:oracle not available 的方法
  6. kruskal 重构树(讲解 + 例题)
  7. 【Docker】docker bash: sudo: command not found
  8. SQL.变量、运算符、if、while
  9. 代码段:js表单提交检测
  10. Flutter之RenderView RenderObject ParentData知识点梳理
  11. 可以用c语言改笔记本键盘灯,背光键盘B/C面设计_笔记本评测-中关村在线
  12. 疯狂java讲义第八章课后习题答案
  13. Stream.of()用法示例
  14. 恍恍惚惚,哈哈,35. Search Insert Position
  15. 安全左中右·2022 XDR 网络安全运营新理念峰会圆满落幕
  16. c语言求最小公倍数_最小公倍数
  17. 【计算机网络基础 七】输入URL到浏览器发生了什么
  18. Linux终端出现:To run a command as administrator (user “root“), use “sudo <command>“.
  19. cron定时怎么设置
  20. CentOS 安装 Docker 教程

热门文章

  1. 浅谈一个缓存小实践,另外还有更多案例,欢迎关注~
  2. 简单的combineByKey算子【看完就懂系列】
  3. java基础--网络编程
  4. JAVA程序设计----集合基础之Collection
  5. 如果你想写自己的Benchmark框架
  6. 突发!HashiCorp禁止在中国使用企业版VAULT软件
  7. linux out 日志,关于Linux中nohup.out日志过大问题(示例代码)
  8. MyBatis拦截器原理探究
  9. 【测试点分析】1035 Password (20 分)
  10. 如何使 子页面顶部栏 覆盖app.json中的顶部栏