Onioncy 2019-06-28
下图是最终的结果:
首先我们找到豆瓣的编程类书籍网址:
https://book.douban.com/tag/编程
进入网址之后我们翻到最下面的分页导航:
通过分析分页地址我们可以得出:
https://book.douban.com/tag/%...{偏移量}&type=T
这个地址则是我们要采集的内容。第一页 start = 0,第二页 start = 20 ... 以此类推。
找到了要采集的 URL 之后,接下来就是分析我们真正需要的数据在 HTML 文档中的位置。
F12 打开控制台发现,这些 li 标签正是我们的目标内容。
而书名、评论、评分分别对应li 下面的 h2 标签、class 为 rating_nums 的 span 标签, class 为 pl 的 span 标签。
见下图:
有了以上内容,那么我们很容易就有了思路:
除了上次使用到的 requests, BeautifulSoup, 还增加了几个包。
这个函数的主要功能就是抓取指定页码所有的书的信息,包括书名、评分、评论数。并且保存到一个二维数组中。
代码解读:
因为豆瓣的分页是根据 URL 中的 start 参数(相当于偏移量)来分的,所以在刚开始定义了一个 offset 变量,根据我们传入的页码来计算正确的 start 参数的值。
后面通过 find_all 方法获取所有的 li 对象,存入 book_info_list 列表中,那么接下来就是遍历这个列表,从每一个元素中得到 star、 title、comment 三个变量。最终得到一个二维数组 result。
以上则是我们爬取豆瓣的小案例,有经验的朋友们会发现这个案例有很大的不足之处。
在运行这个程序的时候,我们会发现会非常缓慢。原因就是每次请求豆瓣的分页 URl 之后,接下来紧跟着一条龙的获取书名等操作,获取完这个页面的所有数据之后再接着抓取下一个分页页面。也就是完全同步的编码方式。所以慢是必然的。
那么如何调整代码结构才能使程序运行迅速呢?
这里介绍一个简单又常用的方法:
我们可以采用多线程技术,python 的 threading 包是专门用于多线程处理的。采用这种方式又多增加了两个包:
可以将上述代码的下载分页 URL 部分代码放入一个单独的线程去跑,并将下载好的 HTML 文档存入一个队列中。然后多开几个线程去队列中读取数据,并用 BS4 来分析,将分析得到的 list 数据结构追加到外部的另一个list 中。最后再去排序这另一个列表。
获取源码请到:“ 后端漫谈 ” 公众号后台回复 “douban”。