2016-11-30 39 views
0

我用Python做了简单的网络爬虫。到目前为止,它所做的一切都会创建一组应该访问的网址,这是一组已经访问过的网址。在解析页面时,它会将该页面上的所有链接添加到应该访问的集合中,并将页面url添加到已访问的集合中,等等,而should_be_visited的长度大于0.到目前为止,它在一个线程中执行所有操作。针对网络爬虫的Python线程或多处理?

现在我想为此应用程序添加并行性,所以我需要具有相同类型的链接和很少的线程/进程,其中每个将从should_be_visited中弹出一个url并更新already_visited。我真的迷失在线程和多处理,我应该使用,我需要一些池,队列吗?

+0

对于要访问的URL集合,它们中的很多是同一台服务器还是全部来自不同的服务器? – halfer

+0

所有的都是一样的 – wasd

+1

好的,在这种情况下,你可能根本不应该平行,除非服务器在你的控制之下,并且你的服务器/网络能够处理负载。对于远程管理员认为拒绝服务攻击的请求,您应该在每个请求之间稍稍延迟一段时间,而不是加快请求速度,可能会延迟一两秒。广泛的抓取规则是**它应该慢慢完成,而不是快速**,并且未能观察到这可能会将您的服务器放在IP阻止列表中。 – halfer

回答

1

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

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

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

(当然,尊重robots.txt的,和不困请求过多而服务器:-)

0

另一种方法是异步I/O,这是很多这类的我更好/ O-bound任务(除非处理页面是真的昂贵)。您可以使用asyncioTornado来尝试使用它的httpclient