【Python3爬虫】用Python中的队列来写爬虫

一、写在前面

当你看着你的博客的阅读量慢慢增加的时候,内心不禁有了些小激动,但是不得不吐槽一下--博客园并不会显示你的博客的总阅读量是多少。而这一篇博客就将教你怎么利用队列这种结构来编写爬虫,最终获取你的博客的总阅读量。

二、必备知识

队列是常用数据结构之一,在Python3中要用queue这个模块来实现。queue这个模块实现了三种队列:

class queue.Queue(maxsize=0):FIFO队列(first in first out),先进先出,第一个进入队列的元素会第一个从队列中出来。maxsize用于设置队列里的元素总数,若小于等于0,则总数为无限大。

class queue.LifoQueue(maxsize=0):LIFO队列(last in first out),后进先出,最后一个进入队列的元素会第一个从队列中出来。maxsize用于设置队列里的元素总数,若小于等于0,则总数为无限大。

class queue.PriorityQueue(maxsize=0):优先级队列(first in first out),给队列中的元素分配一个数字标记其优先级。maxsize用于设置队列里的元素总数,若小于等于0,则总数为无限大。

这次我使用的是Queue这个队列,Queue对象中包含的主要方法如下:

Queue.put(item, block=True, timeout=None):将元素放入到队列中。block用于设置是否阻塞,如果timeout为正数,表明最多阻塞多少秒。

Queue.get(block=True, timeout=None):从队列中删除并返回一个元素,如果队列为空,则报错。block用于设置是否阻塞,如果timeout为正数,表明最多阻塞多少秒。

Queue.empty():判断队列是否为空,如果队列为空,返回False,否则返回True。

三、具体步骤

首先进入博客,然后打开开发者工具选择查看元素,如下:

这里只要定位到类名为postDesc的div节点就可以提取到我们想要的阅读量信息了,这一步是很简单的。问题在于如何实现翻页?先定位到下一页查看一下元素:

好像定位到id为nav_next_page的div节点就行了,是这样吗?点击进入下一页,然后再次定位查看一下:

可以看到用之前定位div节点的方法已经不行了,怎么办呢?我的解决办法是用正则表达式进行匹配,因为下一页对应的元素都是这样的:

<a href="链接">下一页</a>

所以只需要进行一下正则匹配就能获取下一页的链接了,如果获取不到,就说明已经是最后一页了!

四、完整代码

 1 """
 2 Version: Python3.5
 3 Author: OniOn
 4 Site: http://www.cnblogs.com/TM0831/
 5 Time: 2019/3/11 10:46
 6 """
 7 import re
 8 import queue
 9 import requests
10 from lxml import etree
11
12
13 class CrawlQueue:
14     def __init__(self):
15         """
16         初始化
17         """
18         self.q = queue.Queue()  # 爬取队列
19         self.username = input("请输入您的博客名称:")
20         self.q.put("http://www.cnblogs.com/" + self.username)
21         self.urls = ["http://www.cnblogs.com/" + self.username]  # 记录爬取过的url
22         self.result = []  # 储存阅读量数据
23
24     def request(self, url):
25         """
26         发送请求和解析网页
27         :param url: 链接
28         :return:
29         """
30         res = requests.get(url)
31         et = etree.HTML(res.text)
32         lst = et.xpath(‘//*[@class="postDesc"]/text()‘)
33         for i in lst:
34             num = i.split(" ")[5].lstrip("阅读(").rstrip(")")
35             self.result.append(int(num))
36
37         # 下一页
38         next_page = re.search(‘<a href="(.*?)">下一页</a>‘, res.text)
39         if next_page:
40             href = next_page.group().split(‘&nbsp;‘)[-1].replace(‘<a href="‘, ‘‘).replace(‘">下一页</a>‘, ‘‘)
41             if href not in self.urls:  # 确保之前没有爬过
42                 self.q.put(href)
43                 self.urls.append(href)
44
45     def get_url(self):
46         """
47         从爬取队列中取出url
48         :return:
49         """
50         if not self.q.empty():
51             url = self.q.get()
52             self.request(url)
53
54     def main(self):
55         """
56         主函数
57         :return:
58         """
59         while not self.q.empty():
60             self.get_url()
61
62
63 if __name__ == ‘__main__‘:
64     crawl = CrawlQueue()
65     crawl.main()
66     print("您的博客总阅读量为:{}".format(sum(crawl.result)))

完整代码已上传到GitHub

原文地址:https://www.cnblogs.com/TM0831/p/10510319.html

时间: 2024-10-31 15:04:26

【Python3爬虫】用Python中的队列来写爬虫的相关文章

python中的队列详解

一.Queue简介 python中的队列分类可分为两种: 1.线程Queue,也就是普通的Queue 2.进程Queue,在多线程与多进程会讲解.

python 中无switch(写了几个函数代替switch)

字典的常用用途之一代替switch 在C/C++/Java语言中,有个很方便的函数switch,比如: 复制代码代码如下: public class test {            public static void main(String[] args) {          String s = "C";          switch (s){          case "A":               System.out.println(&qu

python中消息队列RabbitMQ的使用

1,简介 RabbitMQ(Rabbit Message Queue)是流行的开源消息队列系统,用erlang语言开发. 1.1关键词说明: Broker:消息队列服务器实体.Exchange:消息交换机,它指定消息按什么规则,路由到哪个队列.Queue:消息队列载体,每个消息都会被投入到一个或多个队列.Binding:绑定,它的作用就是把exchange和queue按照路由规则绑定起来.Routing Key:路由关键字,exchange根据这个关键字进行消息投递.vhost:虚拟主机,一个b

【Python】从0开始写爬虫——开发环境

python小白,稍微看了点语法而已, 连字典的切片都永不顺的那种.本身是写java的,其实java也写得菜, 每天下了班不是太想写java.所以下班总是乱搞,什么都涉猎一点,也没什么太实际的收获.现在打算慢慢写个python爬虫玩 1. python环境搭建.我在windows上也是搭了python环境的,很久了.但是这个我在windows用pip安装的第三方库用起来总是报错.所以我一般都不用.我时用pycharm的python环境的. 在pycharm上安装需要的包,新建项目后,在左上角 F

【Python】从0开始写爬虫——把扒到的豆瓣数据存储到数据库

1. 我们扒到了什么? id, 名称, 上映年份,上映日期,所属类目, 导演,主演,片长,评分,星评,评价人数 2. 把这些数据做一个分类. a..基本信息 :名称, 导演,上映年份, 所属类目, 片长 b.评价信息:评分,星评,评价人数 c.主演表: 主演(我在纠结要不要单独列一张表) 3 .表设计.现在有点蛋疼的是主键.用自增主键还是电影id做主键.经过我的多方面考虑,我慎重(草率)地决定,用电影id(反正都要建唯一索引,为什么不拿来当主键呢..), 所以我刚才又在id那转了一下数据 m_i

【Python】从0开始写爬虫——豆瓣电影

1. 最近略忙..java在搞soap,之前是用工具自动生成代码的.最近可能会写一个soap的java调用 2. 这个豆瓣电影的爬虫.扒信息的部分暂时先做到这了.扒到的信息如下 from scrapy import app import re header = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safar

【Python】从0开始写爬虫——转身扒豆瓣电影

豆瓣就比较符合这个“明人不说暗话”的原则.所以我们扒豆瓣,不多说,直接上代码 from scrapy import app import re header = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36', 'Host': 'movie.douban.com', 'Accept-Lan

python中的生成器函数是如何工作的?

以下内容基于python3.4 1. python中的普通函数是怎么运行的? 当一个python函数在执行时,它会在相应的python栈帧上运行,栈帧表示程序运行时函数调用栈中的某一帧.想要获得某个函数相关的栈帧,则必须在调用这个函数且这个函数尚未返回时获取,可能通过inspect模块的currentframe()函数获取当前栈帧. 栈帧对象中的3个常用的属性: f_back : 调用栈的上一级栈帧 f_code: 栈帧对应的c f_locals: 用在当前栈帧时的局部变量; 比如: >>&g

Python中生成器,迭代器,以及一些常用的内置函数.

知识点总结 生成器 生成器的本质就是迭代器. 迭代器:Python中提供的已经写好的工具或者通过数据转化得来的. 生成器:需要我们自己用Python代码构建的 创建生成器的三种方法: 通过生成器函数 通过生成器推导式 python内置函数或者模块提供 生成器函数 yield:一个yield对应一个next,next超过yield数量,就会报错,与迭代器一样. yield与return的区别: return一般在函数中只设置一个,他的作用是终止函数,并传给函数的执行者返回值 yield在生成器中可