Python3爬虫与多线程

本文按如下内容组织:

# 介绍这个爬虫的目的、模块,创造原始单线程爬虫

# 对这个爬虫进行改造,创造多线程爬虫

一、爬虫功能介绍

文章标题取的是《Python爬虫与多线程》,而不是《Python多线程爬虫》,因为爬虫的目的是为了获取数据而非炫技。即使没有多线程,单线程的爬虫也可以完成任务,大不了电脑不关放一夜跑(做量化回测中常有的事)。

下面就介绍这个爬虫的功能,是用来爬取https://quantocracy.com/所有帖子的标题、描述、网址、发布时间,分别对应数据库的四个字段:title、description、url、time。

这个网站的结构非常简单,所以爬虫的逻辑也比较简单:

下面依次介绍代码的实现逻辑:

(1)构造出一页的url,比如https://quantocracy.com/?pg=1,使用自定义的get_html函数获得html内容:

(2)使用Beautiful库解析内容,获得我们需要的信息。通过chrome的审查元素功能可以发现,网页的结构如下图:

加粗的标签是含有信息的标签,所以我们用tags = soup.find_all('div',attrs={'class':'qo-content-col'})找到所有的div标签,每页可以得到五十个标签。

下面使用自定义的get_info函数对每个标签做子解析:

(3)将信息存储到本地文件或数据库。

上述步骤(2)返回了一条[title, description, url, time]的信息,然后不断把这条信息append到results列表中,就得到了所有信息。当循环完所有页面时,我们可以把results转成pd.DataFrame,然后存储到本地csv。

以上,我们实现了一个功能完整的单线程爬虫,耗时在十几分钟。第二部分讨论可以在哪些环节降低延迟。

二、多线程爬虫

上文的爬虫流程:获取页面 -> 解析页面 -> 数据存储,在这些环节中的耗时分别是:

(1)获取页面,由于网络延迟,一页通常需要1-2s,这是最主要的延迟;

(2)数据存储,由于是存储到本地数据库,速度较快。

下面考虑怎么降低延迟:

(1)创建一个Consumer类和多个实例,用于对每个页面的获取、解析和存储。

(2)用一个队列Queue对象,来实现Consumer类不断获取网址。

代码逻辑如下:

先产生所有url,put进队列;

然后产生八个消费者,用于不断从队列中取出网址,进行获取、解析和存储;

所有信息存储到内存中,然后批量存储到数据库或csv。

这个流程下来,有八个worker并行工作,所以效率提升很多。

Consumer类的代码如下:

三、最后呈现的数据长这样:

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181103G1B7WS00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券