摘要:上一次的抓取豆瓣高分计算机书籍的案例,采用的是完全同步的方式。是用来进行多线程编程的,也就是用来创建队列。同时这个函数也是由多个解析线程执行。
上一次的抓取豆瓣高分计算机书籍的案例,采用的是完全同步的方式。即单个线程依次执行完所有的逻辑,这样存在的问题就是我们的爬虫程序会非常的慢。
所以本文作为上一次案例的升级版本,通过循序渐进、动手实践的方式来达到更好的学习效果。
import requests from bs4 import BeautifulSoup import re import numpy as np import csv import time import threading import queue
本次新增了两个包,threading 和 queue。threading 是用来进行多线程编程的,queue 也就是用来创建队列。至于更详细的使用方法,可以上网自行学习。这里就不多做介绍了。
生成 URL
创建两个队列,一个用保存生成的URL(队列1),一个保存HTML文档(队列2)
创建若干个线程来下载 HTML,并且保存到队列2
创建若干个线程解析文档
排序并保存
代码:以上前三个方法都没有改动,主要是第四个和第五个。
req_page(): 用来请求url。
def req_page(): while True: try: url = url_task.get(block=False) resp = requests.get(url) html = resp.text task_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: continue title = book_info.find("h2").get_text().replace(" ", "").replace(" ", "") 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: continue except: 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() 方法,那么在最后执行排序和保存操作的时候,所有的子线程都已经执行完毕了。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/44777.html
摘要:本文将通过来爬取豆瓣编程类评分大于的书籍。下图是最终的结果下面进入正题一采集源分析首先我们找到豆瓣的编程类书籍网址编程进入网址之后我们翻到最下面的分页导航通过分析分页地址我们可以得出偏移量这个地址则是我们要采集的内容。 对于很多正在学习计算机的朋友来说,选择合适的学习材料是非常重要的。 本文将通过 Python 来爬取豆瓣编程类评分大于 9.0 的书籍。 此案例很适合入门爬虫的朋友学习...
摘要:今天为大家整理了个爬虫项目。地址新浪微博爬虫主要爬取新浪微博用户的个人信息微博信息粉丝和关注。代码获取新浪微博进行登录,可通过多账号登录来防止新浪的反扒。涵盖链家爬虫一文的全部代码,包括链家模拟登录代码。支持微博知乎豆瓣。 showImg(https://segmentfault.com/img/remote/1460000018452185?w=1000&h=667); 今天为大家整...
阅读 3841·2021-11-16 11:44
阅读 3097·2021-11-12 10:36
阅读 3353·2021-10-08 10:04
阅读 1227·2021-09-03 10:29
阅读 371·2019-08-30 13:50
阅读 2571·2019-08-29 17:14
阅读 1719·2019-08-29 15:32
阅读 1050·2019-08-29 11:27