上一次的抓取豆瓣高分计算机书籍的案例,采用的是完全同步的方式。即单个线程依次执行完所有的逻辑,这样存在的问题就是我们的爬虫程序会非常的慢。

所以本文作为上一次案例的升级版本,通过循序渐进、动手实践的方式来达到更好的学习效果。

相对于上次的案例,本次主要采用多线程+队列的方式来实现。
用到的包:
import requests
from bs4 import BeautifulSoup
import re
import numpy as np
import csv
import time
import threading
import queue

本次新增了两个包,threading 和 queue。threading 是用来进行多线程编程的,queue 也就是用来创建队列。至于更详细的使用方法,可以上网自行学习。这里就不多做介绍了。

主要流程:
  1. 生成 URL
  2. 创建两个队列,一个用保存生成的URL(队列1),一个保存HTML文档(队列2)
  3. 创建若干个线程来下载 HTML,并且保存到队列2
  4. 创建若干个线程解析文档
  5. 排序并保存

代码:

以上前三个方法都没有改动,主要是第四个和第五个。

req_page(): 用来请求url。

def req_page():while True:try:url = url_task.get(block=False)resp = requests.get(url)html = resp.texttask_html.put(html)time.sleep(1)except:break

以上代码会被若干个线程执行,每一个线程的流程都是不段的从 url_task 也就是我们创建的队列1中取出一个URL,然后执行请求,并把下载到的 HTML 放入队列2。这里有两点要注意的。第一个点就是通过 url_task.get() 方法从队列里拿出任务的时候,由于我们的队列1是提前设定好的,也就是说当下载线程取任务的时候并不会发生 queue.Empty 的异常。只有当队列中的数据被处理完的时候才会执行 except,那么线程就可以通过这个来退出。第二点是sleep这块 ,因为请求太频繁会被豆瓣封掉IP。

get_content():

def get_content():if task_html.qsize() > 10:while True:try:html = task_html.get(block=False)bs4 = BeautifulSoup(html, "lxml")book_info_list = bs4.find_all('li', class_='subject-item')if book_info_list is not None:for book_info in book_info_list:list_ = []try:star = book_info.find('span', class_='rating_nums').get_text()if float(star) < 9.0:continuetitle = book_info.find('h2').get_text().replace(' ', '').replace('\n', '')comment = book_info.find('span', class_='pl').get_text()comment = re.sub("\D", "", comment)list_.append(title)list_.append(comment)list_.append(star)task_res.append(list_)except:continueexcept:break

这个函数首先判断一下 HTML 文档队列(队列2)的大小是不是大于10,目的是防止解析线程比下载线程执行的快,如果解析线程快于下载线程,那么再还没有下载完所有的URL时,就触发队列的 queue.Empty异常,从而过早退出线程。中间的代码也是上次案例中的代码,不同之处也就是以前是从列表中读取,现在是从队列中读取。同时这个函数也是由多个解析线程执行。

主函数:

# 生成分页url
url_list = make_url(50)
# url 队列 (队列1)
url_task = queue.Queue()
for url in url_list:url_task.put(url)
# 下载好的html队列 (队列2)
task_html = queue.Queue()
# 最终结果列表
task_res = []
threads = []
# 获取html线程
for i in range(5):threads.append(threading.Thread(target=req_page))
# 解析html线程
threads.append(threading.Thread(target=get_content))
threads.append(threading.Thread(target=get_content))
for i in threads:i.start()i.join()
# 主线程排序保存
save(_sort(task_res))

主函数的流程也就是最开始写的五个流程。因为我们创建的所有线程都调用了 join() 方法,那么在最后执行排序和保存操作的时候,所有的子线程都已经执行完毕了。

循序渐进学爬虫:多线程+队列爬取豆瓣高分计算机类书籍相关推荐

  1. 循序渐进学爬虫:多线程+队列爬取豆瓣高分计算机类书籍 1

    上一次的抓取豆瓣高分计算机书籍的案例,采用的是完全同步的方式.即单个线程依次执行完所有的逻辑,这样存在的问题就是我们的爬虫程序会非常的慢. 所以本文作为上一次案例的升级版本,通过循序渐进.动手实践的方 ...

  2. Python简单爬虫(以爬取豆瓣高分图书为例)

    前言 浏览器或程序的一次请求,网站服务器的一次响应,就构成一次网络爬虫行为. 一个爬虫通常通过爬虫包完成请求HTML,通过解析包完成HTML解析和存储. 爬虫分类: 全网爬虫 爬取整个互联网,需要定制 ...

  3. Python爬虫实战(1) | 爬取豆瓣网排名前250的电影(下)

    在Python爬虫实战(1) | 爬取豆瓣网排名前250的电影(上)中,我们最后爬出来的结果不是很完美,这对于"精益求精.追求完美的"程序猿来说怎么能够甘心 所以,今天,用pyth ...

  4. Python爬虫入门(爬取豆瓣电影信息小结)

    Python爬虫入门(爬取豆瓣电影信息小结) 1.爬虫概念 网络爬虫,是一种按照一定规则,自动抓取互联网信息的程序或脚本.爬虫的本质是模拟浏览器打开网页,获取网页中我们想要的那部分数据. 2.基本流程 ...

  5. Python爬虫入门 | 4 爬取豆瓣TOP250图书信息

      先来看看页面长啥样的:https://book.douban.com/top250   我们将要爬取哪些信息:书名.链接.评分.一句话评价--   1. 爬取单个信息 我们先来尝试爬取书名,利用之 ...

  6. scrapy爬虫之crawlspide爬取豆瓣近一周同城活动

    简介 本文主要介绍crawlspider爬取豆瓣近一周同城活动. 要点:item/itemloader利用input_processor/output_processor对爬取的数据进行过滤. 实现 ...

  7. python爬虫——Cookie登录爬取豆瓣短评和影评及常见问题

    python爬虫--Cookie登录爬取豆瓣短评和影评 常见问题(本文已解决) 具体步骤 一.获取网页源码 短评.影评 二.解析网页源码及爬取评论 1.短评网页解析 ①确定位置 2.短评爬取 ①名称爬 ...

  8. Python爬虫:现学现用xpath爬取豆瓣音乐

    爬虫的抓取方式有好几种,正则表达式,Lxml(xpath)与BeautifulSoup,我在网上查了一下资料,了解到三者之间的使用难度与性能 三种爬虫方式的对比. 这样一比较我我选择了Lxml(xpa ...

  9. python爬虫爬取豆瓣电影信息城市_Python爬虫入门 | 2 爬取豆瓣电影信息

    这是一个适用于小白的Python爬虫免费教学课程,只有7节,让零基础的你初步了解爬虫,跟着课程内容能自己爬取资源.看着文章,打开电脑动手实践,平均45分钟就能学完一节,如果你愿意,今天内你就可以迈入爬 ...

最新文章

  1. cv2.threshholding()简单阈值、自适应阈值,Octus阈值
  2. ORACLE 字符串函数用法(转载)
  3. C++ Primer 5th笔记(chap 18 大型程序工具)类型转换与多个基类
  4. 事件,信号量,互斥量
  5. Python学习笔记:Day13 提升开发效率
  6. python_base_while循环、for循环
  7. 对数据类型而言运算符无效。运算符为 add,类型为 text。
  8. Atitit 通过调用gui接口杀掉360杀毒 360卫士  qq保镖等难以结束的进程(javac# php )
  9. 诺基亚java闪退_回顾诺基亚N9:诺基亚手机颜值巅峰,却在发布7天后被“放弃”...
  10. Diablo 大菠萝
  11. 查询ISBN号验证ISBN号调用api接口查询书籍信息
  12. 论如何成为技术大牛,GitHub中国区前20名详解
  13. 052试题 97 - SQL*Loader Direct Path and Conventional Path
  14. 正弦余弦指引的乌鸦搜索算法-附代码
  15. bootstrap的datetimepicker使用(1.将默认的英文设置为中文2.选择日月年的时候记录之前的操作)...
  16. 云e办学习笔记(十六)Redis集成菜单
  17. 解:一阶齐次或非齐次线性微分方程-详细推导
  18. 华云数据出席2021信创发展论坛:喜获信创双项殊荣 发布业内首个《信创云基座白皮书》
  19. 简历被公司浏览分布图-来自前程无忧
  20. 关于Rigidbody,Collider和CharacterController三者之间的关系和用法的总结

热门文章

  1. 怎么判断机械硬盘要多大_秋天要多吃芋头,买芋头是买大的还是小的?学学广西大妈怎么买...
  2. 百度SEO Typecho仿Win95怀旧主题
  3. c语言双精度百分号,C语言输出百分号%的方法和示例
  4. java crs校验_AIX系统学习之-CRS安装后校验
  5. 100套精美英文HTML页面源码
  6. Node.js: 如何继承 events 自定义事件及触发函数
  7. magento创建自定义页面 (Bestseller实例) Bestseller products in Magento
  8. Objective-C的self.用法的一些总结
  9. 图片旋转 rotate
  10. CSS+jQuery实现滑动幻灯片实例详解