案例

it2022-05-05  129

案例_(单线程)使用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"]//h23.内容://div[contains(@id,"qiushi_tag_")]//div[@class="content"]/span4.点赞数://div[contains(@id,"qiushi_tag_")]//span[@class="stats-vote"]/i5.评论数://div[contains(@id,"qiushi_tag_")]//span[@class="stats-comments"]//i6.图片链接://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代理解决,如果嫌麻烦可以爬取一页休眠一秒

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

 

 

转载于:https://www.cnblogs.com/ywk-1994/p/9581036.html


最新回复(0)