案例_(单线程)使用xpath爬取糗事百科

案例_(单线程)使用xpath爬取糗事百科

步骤如下:

首先通过xpath插件找出我们要爬取的信息的匹配规则

url = "https://www.qiushibaike.com/8hr/page/1/"

xpath插件的模糊查询:contains(),第一个参数是要匹配的标签,第二个参数是这个标签的部分内容

1.//div[contains(@id,"qiushi_tag_")] 匹配出所有段子包括评论,点赞数  以此作为根节点

2.用户名://div[contains(@id,"qiushi_tag_")]/div[@class="author clearfix"]//h2

3.内容://div[contains(@id,"qiushi_tag_")]//div[@class="content"]/span

4.点赞数://div[contains(@id,"qiushi_tag_")]//span[@class="stats-vote"]/i

5.评论数://div[contains(@id,"qiushi_tag_")]//span[@class="stats-comments"]//i

6.图片链接://div[contains(@id,"qiushi_tag_")]//div[@class="thumb"]//@src

代码如下

 1 from urllib.request import *
 2 import time
 3 from lxml import etree
 4 
 5 
 6 class Spider(object):
 7     def __init__(self):
 8         # 定义一个空列表装所有信息
 9         self.__info = []
10 
11         # 定义一个字典保存每条段子的信息
12         self.__item = {}
13 
14         # 用户输入开始页面和结束页面
15         self.__start_page = int(input("请输入开始爬取的页面:"))
16         self.__end_page = int(input("请输入结束爬取的页面:"))
17 
18         self.__header = {
19             "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3514.0 Safari/537.36"}
20 
21     def __load_page(self, url):
22         """构建request请求,并发起请求"""
23         request = Request(url, headers=self.__header)
24 
25         # 发送请求获取html源码
26         # response 为<class 'http.client.HTTPResponse'>对象
27         # response.read()  为<class 'bytes'>对象
28         # response.read().decode() 为字符串对象
29         response = urlopen(request)
30         html = response.read().decode()
31 
32         # 调用方法使用xpath获取信息
33         return html
34 
35     def __xpath_get_info(self, html):
36         """将HTML字符串解析为HTML DOM格式,并获取相关信息"""
37         selector = etree.HTML(html)
38 
39         # 返回所有段子的节点位置,contant()模糊查询方法,第一个参数是要匹配的标签,第二个参数是这个标签的部分内容
40         # 每个节点包括一条完整的段子(用户名,段子内容,点赞,评论等)
41         node_list = selector.xpath('//div[contains(@id,"qiushi_tag_")]')
42 
43         for node in node_list:
44             # 爬取所有用户名信息
45             # 取出标签里的内容,使用.text方法
46             user_name = node.xpath('./div[@class="author clearfix"]//h2')[0].text
47 
48             # 爬取段子内容,匹配规则必须加点  不然还是会从整个页面开始匹配
49             # 注意:如果span标签中有br 在插件中没问题,在代码中会把br也弄进来
50             duanzi_info = node.xpath('.//div[@class="content"]/span')[0].text.strip()
51 
52             # 爬取段子的点赞数
53             vote_num = node.xpath('.//span[@class="stats-vote"]/i')[0].text
54 
55             # 爬取评论数
56             comment_num = node.xpath('.//span[@class="stats-comments"]//i')[0].text
57 
58             # 爬取图片链接
59             # 属性src的值,所以不需要.text
60             img_url = node.xpath('.//div[@class="thumb"]//@src')
61             if len(img_url) > 0:
62                 img_url = img_url[0]
63             else:
64                 img_url = "无图片"
65 
66             self.__save_info(user_name, duanzi_info, vote_num, comment_num, img_url)
67 
68     def __save_info(self, user_name, duanzi_info, vote_num, comment_num, img_url):
69         """把每条段子的相关信息写进字典"""
70         item = {
71             "username": user_name,
72             "content": duanzi_info,
73             "zan": vote_num,
74             "comment": comment_num,
75             "image_url": img_url
76         }
77         self.__info.append(item)
78 
79     def show_result(self):
80         """展示爬取的结果"""
81         for info in self.__info:
82             print(info)
83 
84     def run(self):
85         """启动爬虫程序"""
86         for page in range(self.__start_page, self.__end_page + 1):
87             url = "https://www.qiushibaike.com/8hr/page/" + str(page)
88             html = self.__load_page(url)
89 
90             # 爬取一页休眠一秒,应对反爬策略
91             # time.sleep(1)
92             self.__xpath_get_info(html)
93 
94 
95 if __name__ == '__main__':
96     qiushi_spider = Spider()
97     qiushi_spider.run()
98     qiushi_spider.show_result()
 

结果预览:

 
可能出现的问题
问题:一次爬取多个以上页面会出现:urllib.error.HTTPError: HTTP Error 503: Service Temporarily Unavailable
原因: 一种反爬虫机制,即限制了单个ip在固定时间内访问的次数,可以采用切换ip代理解决,如果嫌麻烦可以爬取一页休眠一秒


如果你和我有共同爱好,我们可以加个好友一起交流哈!

猜你喜欢

转载自blog.csdn.net/ywk_hax/article/details/82505510