【问题标题】:Python threading or multiprocessing for web-crawler?用于网络爬虫的 Python 线程或多处理?
【发布时间】:2016-11-30 17:23:23
【问题描述】:

我已经用 Python 制作了简单的网络爬虫。到目前为止,它所做的一切都创建了一组应该访问的 url,一组已经访问过的 url。在解析页面时,它将该页面上的所有链接添加到应该访问的集合和页面 url 到已经访问的集合,依此类推,而 should_be_visited 的长度> 0。到目前为止,它在一个线程中完成所有操作。

现在我想为这个应用程序添加并行性,所以我需要有一组相同类型的链接和少量线程/进程,每个线程/进程都会从 should_be_visited 中弹出一个 url 并更新 already_visited。我真的迷失在线程和多处理方面,我应该使用它们,我需要一些池、队列吗?

【问题讨论】:

  • 对于这组要访问的URL,是很多都是同一个服务器,还是都来自不同的服务器?
  • 同一个
  • 好的,在这种情况下,您可能根本不应该并行化,除非服务器在您的控制之下并且您的服务器/网络能够处理负载。而不是加快您的请求,这在远程管理员看来是一种拒绝服务攻击,您应该在每个请求之间设置一个小的延迟,也许是一两秒。抓取的广泛规则是应该慢慢完成,而不是快速完成,如果不遵守这一点,可能会将您的服务器置于 IP 阻止列表中。

标签: python multithreading web-crawler python-multithreading


【解决方案1】:

在决定是否在 Python 中使用线程时,经验法则是询问线程将执行的任务是 CPU 密集型还是 I/O 密集型。如果答案是 I/O 密集型的,那么您可以使用线程。

由于 GIL,Python 解释器一次只能运行一个线程。如果一个线程正在做一些 I/O,它将阻塞等待数据变得可用(例如从网络连接或磁盘),同时解释器将上下文切换到另一个线程。另一方面,如果线程正在执行 CPU 密集型任务,则其他线程将不得不等到解释器决定运行它们。

网络爬虫大多是面向 I/O 的任务,你需要建立一个 HTTP 连接,发送一个请求,等待响应。是的,在你得到响应后,你需要花费一些 CPU 来解析它,但除此之外,它主要是 I/O 工作。所以,我相信在这种情况下线程是一个合适的选择。

(当然,请尊重 robots.txt,不要向服务器发起过多请求 :-)

【讨论】:

    【解决方案2】:

    另一种选择是异步 I/O,这对于这种 I/O 密集型任务要好得多(除非处理一个页面真的很昂贵)。您可以同时使用asyncioTornado,使用其httpclient

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多