Python 网络爬虫的线程或多处理?
Python threading or multiprocessing for web-crawler?
我用 Python 制作了简单的网络爬虫。到目前为止,它所做的一切都创建了应该访问的 url 集,已经访问过的 url 集。在解析页面时,它将该页面上的所有链接添加到应该访问的集合中,并将页面 url 添加到已经访问的集合中,依此类推,而 should_be_visited 的长度 > 0。到目前为止,它完成了所有内容一个线程。
现在我想向该应用程序添加并行性,因此我需要具有相同类型的链接集和少量线程/进程,其中每个线程/进程将从 should_be_visited 中弹出一个 url 并更新already_visited。我真的迷失了线程和多处理,我应该使用它们,我需要一些池、队列吗?
决定是否在 Python 中使用线程的经验法则是询问线程将执行的任务是 CPU 密集型还是 I/O 密集型。如果答案是 I/O 密集型,那么您可以使用线程。
由于 GIL,Python 解释器将 运行 一次只有一个线程。如果一个线程正在做一些 I/O,它会阻塞等待数据变得可用(例如,从网络连接或磁盘),同时解释器将上下文切换到另一个线程。另一方面,如果线程正在执行 CPU 密集型任务,则其他线程将不得不等到解释器决定 运行 它们。
网络抓取主要是一项面向I/O的任务,您需要建立HTTP 连接、发送请求、等待响应。是的,在您获得响应后,您需要花费一些 CPU 来解析它,但除此之外,它主要是 I/O 的工作。所以,我相信,在这种情况下,线程是一个合适的选择。
(当然,尊重 robots.txt,不要用太多的请求冲击服务器 :-)
另一种选择是异步 I/O,这对于这种 I/O 绑定的任务要好得多(除非处理一个页面 真的 很昂贵) .您可以尝试使用 asyncio or Tornado, using its httpclient.
我用 Python 制作了简单的网络爬虫。到目前为止,它所做的一切都创建了应该访问的 url 集,已经访问过的 url 集。在解析页面时,它将该页面上的所有链接添加到应该访问的集合中,并将页面 url 添加到已经访问的集合中,依此类推,而 should_be_visited 的长度 > 0。到目前为止,它完成了所有内容一个线程。
现在我想向该应用程序添加并行性,因此我需要具有相同类型的链接集和少量线程/进程,其中每个线程/进程将从 should_be_visited 中弹出一个 url 并更新already_visited。我真的迷失了线程和多处理,我应该使用它们,我需要一些池、队列吗?
决定是否在 Python 中使用线程的经验法则是询问线程将执行的任务是 CPU 密集型还是 I/O 密集型。如果答案是 I/O 密集型,那么您可以使用线程。
由于 GIL,Python 解释器将 运行 一次只有一个线程。如果一个线程正在做一些 I/O,它会阻塞等待数据变得可用(例如,从网络连接或磁盘),同时解释器将上下文切换到另一个线程。另一方面,如果线程正在执行 CPU 密集型任务,则其他线程将不得不等到解释器决定 运行 它们。
网络抓取主要是一项面向I/O的任务,您需要建立HTTP 连接、发送请求、等待响应。是的,在您获得响应后,您需要花费一些 CPU 来解析它,但除此之外,它主要是 I/O 的工作。所以,我相信,在这种情况下,线程是一个合适的选择。
(当然,尊重 robots.txt,不要用太多的请求冲击服务器 :-)
另一种选择是异步 I/O,这对于这种 I/O 绑定的任务要好得多(除非处理一个页面 真的 很昂贵) .您可以尝试使用 asyncio or Tornado, using its httpclient.