• 案例_(单线程)使用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代理解决,如果嫌麻烦可以爬取一页休眠一秒


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

  • 相关阅读:
    MySQL 5.5版本数据库介绍与二进制安装
    nginx配置文件的基础优化
    yum源是什么
    微服务之间调用token管理
    微服务之间调用事务处理
    idea
    sentry
    infinispan配置
    微服务事务处理
    高并发处理
  • 原文地址:https://www.cnblogs.com/ywk-1994/p/9581036.html
Copyright © 2020-2023  润新知