用于大容量 Web 抓取的 Python 线程与 Gevent
Posted
技术标签:
【中文标题】用于大容量 Web 抓取的 Python 线程与 Gevent【英文标题】:Python Threading vs Gevent for High Volume Web Scraping 【发布时间】:2018-02-04 14:02:08 【问题描述】:我正在尝试决定是否应该使用 gevent 或线程在 python 中实现 web 抓取的并发性。
我的程序应该能够支持大量(~1000)并发工作人员。大多数时候,工作人员会等待请求返回。
一些指导性问题: 线程和greenlet之间到底有什么区别?我应该在单个进程中创建的最大线程数是多少(关于服务器的规范)?
【问题讨论】:
太宽泛了?如果您有多个问题,请提出多个问题。 我认为你也应该考虑 asyncio。为了回答您的问题,greenlet 通常比普通线程的重量更轻,这意味着创建许多线程和在它们之间切换的开销更少。然而,因此它们之间共享更多,在某些情况下,这可能是一个问题。您确实需要查看更长的教程才能获得更好的想法。 【参考方案1】:我认为你没有考虑过这整件事。我已经使用从 Gevent 框架创建的 Greenlets 完成了一些相当轻量级的线程应用程序。只要您允许控制在具有适当睡眠或开关的 Greenlets 之间切换 - 一切都会正常工作。建议不要阻塞或等待回复,而是等待或阻塞超时,引发并除外,然后休眠(在代码的除外部分中),然后再次循环 - 否则您将不会轻易切换 Greenlets。
此外,请注意加入和/或杀死所有 Greenlets,因为您最终可能会遇到僵尸,导致您不想要的大量效果。
但是,我不建议您将其用于您的应用程序。相反,以下使用 Gevent 的 Websockets 扩展之一...查看此链接
Websockets in Flask
还有这个链接
https://www.shanelynn.ie/asynchronous-updates-to-a-webpage-with-flask-and-socket-io/
我用 Flask-SocketIO 实现了一个非常不错的应用程序
https://flask-socketio.readthedocs.io/en/latest/
它在 Docker 容器中非常好地通过 Gunicorn 和 nginx 运行。 SocketIO 与客户端的 javascript 接口非常好。
(小心网络抓取 - 使用 Scrapy 之类的东西并启用适当的道德抓取)
【讨论】:
【参考方案2】:python 线程是由操作系统控制的操作系统线程,这意味着它要重得多,因为它需要上下文切换,但绿色线程是轻量级的,因为它在用户空间中,操作系统不会创建或管理它们。
我认为您可以使用gevent
、Gevent = eventloop(libev) + coroutine(greenlet) + monkey patch
、Gevent 为您提供线程,但不使用线程,您可以编写普通代码但具有异步 IO。
确保你的代码中没有 CPU 绑定的东西。
【讨论】:
以上是关于用于大容量 Web 抓取的 Python 线程与 Gevent的主要内容,如果未能解决你的问题,请参考以下文章