使用python的requests库爬取糗事百科并用xpath解析数据后存入MongoDB

首先我们来到目标站点:https://www.qiushibaike.com/text/ ,往下拖动鼠标我们可以看到一共只有13页的数据,因此我们需要找到请求这些数据的URL,并找到这些URL的提交规律。

**1、**打开chrome的开发者工具,切换到Network后刷新页面,观察到服务器返回给我们的东西里只有第一个请求URL:https://www.qiushibaike.com/text/ 里有我们所需要的数据,切换到Response可以找到所需要的数据,如下图所示:
在这里插入图片描述
接着我们点击下一页获取更多的信息,并找到对相应的URL为:https://www.qiushibaike.com/text/page/2/ ,对URL进行比对分析后我们可以发现其中变化的字段为page后的数字,即页码数,由此我们可以得到一个简化的URL为:https://www.qiushibaike.com/text/page/{“页码数”}/ ,接下来我们开始写爬虫程序。

**2、**由Response中的信息可知,我们所提取的数据在某些节点中,为了能够更好的解析页面信息,此处我们使用XPath解析库来提取节点,然后再调用相应方法获取它的正文内容或者属性值,此外我们还借助chrome浏览器的XPath Helper插件来辅助检查我们所写的匹配规则是否正确。比如以提取用户名为例,如下图所示:
在这里插入图片描述
**3.**对于用户名,用户性别、年龄、及段子好笑数可通过以上方法提取,但是对于内容这部分,有时需点击“查看全文”按钮才能查看全部内容,此时会跳转到另一个页面,比如下面这个:
在这里插入图片描述
为了提取文章的全部内容,我们需先按照上图方法获取它的链接后再发送请求,在新页面继续用XPath来提取,如下图:
在这里插入图片描述
**4.**知道提取规则后,我们开始写爬虫程序。
程序主代码:qiushi.py

from  config import *
from lxml import etree
import pymongo

client = pymongo.MongoClient(MONGO_URL, connect=False)
class QiuShiSprider():
    def __init__(self):
        self.url_temp="https://www.qiushibaike.com/text/page/{}/"
        self.headers={"User-Agent":set_user_agent()}

    def get_url_list(self):
        return [self.url_temp.format(i) for i in range(1,14)]

    def parse_url(self,url):
        response=requests.get(url,headers=self.headers)
        return response.content.decode()

    def get_content_list(self,html_str):
        html=etree.HTML(html_str)
        div_list=html.xpath("//div[@id='content-left']/div")
        for div in div_list:
            item={}
            # 用户名
            item["author_name"]=div.xpath(".//div[contains(@class,'author')]/a/h2/text()")
            item["author_name"] = [i.replace("\n", "") for i in item["author_name"]]
            item["author_name"] = item["author_name"][0] if len(item["author_name"]) > 0 else None
            # 发布者性别
            item["author_gender"]=div.xpath(".//div[contains(@class,'articleGender')]/@class")
            item["author_gender"] =item["author_gender"][0].split(" ")[-1].replace("Icon","") if len(item["author_gender"])>0 else None
            # 发布者年纪
            item["author_age"]=div.xpath(".//div[contains(@class,'articleGender')]/text()")
            item["author_age"]=item["author_age"][0] if len(item["author_age"])>0 else None
            # 段子内容
            content_all= div.xpath(".//div[@class='content']/span[@class='contentForAll']/text()")# 段子内容
            if len(content_all)>0:
                content_url="https://www.qiushibaike.com"+div.xpath(".//a[@class='contentHerf']/@href")[0]
                content_str = self.parse_url(content_url)
                content_html = etree.HTML(content_str)
                item["content"] = content_html.xpath("//div[@class='content']/text()")  # 段子内容
            else:
                item["content"] = div.xpath(".//div[@class='content']/span/text()")
            item["content"]=[i.replace("\n","") for i in item["content"]]
            #好笑数
            item["stats_vote"] = div.xpath(".//span[@class='stats-vote']/i/text()")
            item["stats_vote"]=item["stats_vote"][0] if len(item["stats_vote"])>0 else None
            self.save_to_mongo(item)


    def save_to_mongo(self,content_list):
        db = client[taget_DB]
        if db[taget_TABLE].update_one(content_list, {'$set': content_list}, upsert=True):
            print('Successfully Saved to Mongo', content_list)

    def run(self):
        #1.url_list
        url_list=self.get_url_list()
        #2.遍历,发送请求,获取响应
        for url in url_list:
            html_str=self.parse_url(url)
            #3.提取数据
            self.get_content_list(html_str)

if __name__ == '__main__':
    qiushi=QiuShiSprider()
    qiushi.run()


辅助程序:config.py,用于连接MongoDB,及设置随机请求UA以应对反爬

import random
MONGO_URL = 'localhost'
taget_DB = "QIUSHI"
taget_TABLE = "QIUSHI"

def set_user_agent():
    USER_AGENTS = [
        "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0)",
        "Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 1.0.3705; .NET CLR 1.1.4322)",
        "Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.0.04506.30)",
        "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/523.15 (KHTML, like Gecko, Safari/419.3) Arora/0.3 (Change: 287 c9dfb30)",
        "Mozilla/5.0 (X11; U; Linux; en-US) AppleWebKit/527+ (KHTML, like Gecko, Safari/419.3) Arora/0.6",
        "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.2pre) Gecko/20070215 K-Ninja/2.1.1",
        "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9) Gecko/20080705 Firefox/3.0 Kapiko/3.0",
        "Mozilla/5.0 (X11; Linux i686; U;) Gecko/20070322 Kazehakase/0.4.5"
    ]

    user_agent = random.choice(USER_AGENTS)
    return user_agent

**5.**爬取结果如下图:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_44530979/article/details/87291816