有没有易懂的 Python 多线程爬虫代码?

2016-07-17 12:14:14 +08:00
 MyFaith

看了很多范例,但是还是没有理解,比如要爬取 10 页内容,每页有 30 条数据,那么开启 5 个线程的话,我自己尝试写过,不过这 5 个线程都单独爬取 300 条数据,如何才能做到一个线程爬取两页这样?

7762 次点击
所在节点    Python
26 条回复
hard2reg
2016-07-17 17:31:32 +08:00
好吧。。。是我理解错了
wizardforcel
2016-07-17 17:40:45 +08:00
每个线程拿到自己的编号,然后根据编号排数据。考虑你说的按页面编排,每个线程从“起始页+线程编号*2 ”开始抓,步长为“线程总数*2 ”。不要用一个全局的变量来记录当前位置,锁的开销很大。
tumb8r
2016-07-17 18:07:16 +08:00
@bigtan multiprocessing.dummy 的 Pool.map 容易假死不动
practicer
2016-07-17 19:29:49 +08:00
最近一个月一直在理清爬虫多任务化的问题,结论是在 python 爬虫领域,实现多任务的正确姿势是单线程异步 IO 模型。
在写出同时能爬取多个链接的代码前,楼主必须先理解这个模型的原理:单线程异步 IO 模型的基础---- [事件循环+回调函数] 模型。

先说事件循环,它是一个系统,这个系统内由以下函数组成:
1.连接服务器的函数,
2.发送 GET 请求到服务器的函数,
3.接收并读取服务器响应的函数,
4.最后是解析响应内容用来获取数据的函数;

可以看到这几个函数基本就是我们写普通爬虫代码的一个流程:函数与函数之间都需要等待,也就是说只有函数 1 返回结果后才能执行函数 2 ,函数 2 返回结果后才能执行函数 3 。。。

那么,用事件循环来控制这些函数和写普通爬虫代码有什么不同呢?

答案就是,事件循环可以由程序员手动控制多个爬虫(任务),而不是像多线程那般把分配权交给操作系统随机分配。
当一号爬虫(任务)在执行函数 1 时,一执行完就立即返回(意思就是不等待最后获取值),并将控制权交还给事件循环,交给它之后,开始执行二号爬虫(任务);二号爬虫开始执行函数 1 ,同样,一执行完就立即返回,并将控制权交给事件循环;交给它之后,开始执行三号爬虫(任务),三号爬虫开始执行函数 1 ,同样,一执行完就立即返回。。。以此类推。。

问题来了,当一号爬虫(任务)的函数 1 处理完并返回值后该如何处理这个值?这个时候,回调函数就能派上用场了,回调函数起到通知的作用,告知循环系统在咱们这一号爬虫(任务)有个函数处理完了,要用它返回的结果来执行函数 2 。循环机制听到通知后,便开始执行一号爬虫(任务)的函数 2 。执行函数 2 和执行函数 1 的机制完全相同,也是一执行完就返回,并立即将分配权交给循环机制,这样让循环机制同时地、不停地处理二号、三号、四号。。。爬虫(任务)。

最后,直到一号爬虫获取最终想要爬取的数据,同时,二号、三号、四号。。。爬虫仍在同时工作,没有停止,然后二号爬虫也执行完了所有函数并得到数据,然后是三号、四号。。。

以上就是基于事件循环+回调函数的异步 IO 爬虫模型,虽然是单线程但是效率非常高,像 twisted , tornado 这些流行的异步 IO 库基本都是基于这个模型。但是这种模型也有很多弊端,最令人不爽的两个地方是, 1.调试起来非常恼火,根本看不到 traceback 。 2.一旦事件循环内的函数数量变多,代码逻辑也变的复杂。

So.python 3.4 在基于事件循环+回调函数模型的基础上利用生成器的特性,搞了一套改良版的异步 IO 模型,完美解决了以上两个问题。在 python3.5 进一步迭代,推出了 asyncio 库,再次优化了 python 异步 IO 性能。

目前我会写简单的基于事件循环+回调函数的异步 IO 爬虫,仍在理清基于生成器的异步 IO 模型,如果楼主要深入了解,请参考: http://aosabook.org/en/500L/a-web-crawler-with-asyncio-coroutines.html ( python 之父写的异步爬虫教程)
menc
2016-07-18 15:56:46 +08:00
@deadEgg
1. IO 密集型多线程是可用的。
2 多进程的额外开销太大

爬虫还是应该尽量利用多线程
bobuick
2016-07-18 16:22:14 +08:00
爬虫直接线程模式啊。辣么多 IO 。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/292999

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX