zoukankan      html  css  js  c++  java
  • Python爬虫入门教程 9-100 河北阳光理政投诉板块

    河北阳光理政投诉板块-写在前面

    之前几篇文章都是在写图片相关的爬虫,今天写个留言板爬出,为另一套数据分析案例的教程做做准备,作为一个河北人,遵纪守法,有事投诉是必备的技能,那么咱看看我们大河北人都因为什么投诉过呢?

    今天要爬取的网站地址 http://yglz.tousu.hebnews.cn/l-1001-5-,一遍爬取一遍嘀咕,别因为爬这个网站在去喝茶,再次声明,学习目的,切勿把人家网站爬瘫痪了。

    河北阳光理政投诉板块-开始撸代码

    今天再次尝试使用一个新的模块 lxml ,它可以配合xpath快速解析HTML文档,官网网站 https://lxml.de/index.html
    利用pip安装lxml,如果安装失败,可以在搜索引擎多搜搜,内容很多,100%有解决方案。

    pip install lxml
    

    废话不多说,直接通过requests模块获取百度首页,然后用lxml进行解析

    import requests
    from lxml import etree  # 从lxml中导入etree
    
    response = requests.get("http://www.baidu.com")
    html = response.content.decode("utf-8")
    tree=etree.HTML(html)  # 解析html
    
    print(tree)
    
    

    当你打印的内容为下图所示,你就接近成功了!
    在这里插入图片描述

    下面就是 配合xpath 语法获取网页元素了,关于xpath 这个你也可以自行去学习,非常简单,搜索一下全都是资料,咱就不讲了。

    通过xpath我们进行下一步的操作,代码注释可以多看一下。

    tree=etree.HTML(html)  # 解析html
    hrefs = tree.xpath('//a')  #通过xpath获取所有的a元素
    # 注意网页中有很多的a标签,所以获取到的是一个数组,那么我们需要用循环进行操作
    for href in hrefs:
        print(href)
    

    打印结果如下

    <Element a at 0x1cf64252408>
    <Element a at 0x1cf642523c8>
    <Element a at 0x1cf64252288>
    <Element a at 0x1cf64252308>
    <Element a at 0x1cf64285708>
    <Element a at 0x1cf642aa108>
    <Element a at 0x1cf642aa0c8>
    <Element a at 0x1cf642aa148>
    <Element a at 0x1cf642aa048>
    <Element a at 0x1cf64285848>
    <Element a at 0x1cf642aa188>
    

    在使用xpath配合lxml中,记住只要输出上述内容,就代表获取到东西了,当然这个不一定是你需要的,不过代码至少是没有错误的。

    继续编写代码

    # 注意网页中有很多的a标签,所以获取到的是一个数组,那么我们需要用循环进行操作
    for href in hrefs:
        print(href)
        print(href.get("href")) # 获取html元素属性
        print(href.text)  # 获取a标签内部文字
    
    

    输出结果

    <Element a at 0x1c7b76c2408>
    http://news.baidu.com
    新闻
    <Element a at 0x1c7b76c23c8>
    http://www.hao123.com
    hao123
    <Element a at 0x1c7b76c2288>
    http://map.baidu.com
    地图
    <Element a at 0x1c7b76c2308>
    http://v.baidu.com
    视频
    <Element a at 0x1c7b76f5708>
    http://tieba.baidu.com
    贴吧
    

    现在你已经看到,我们已经获取到了百度首页的所有a标签,并且获取到了a标签的href属性和a标签的文字。有这些内容,你就能很容易的去获取我们的目标网站了。

    河北阳光理政投诉板块-爬取投诉数据

    找到我们的目标网页,结果发现,出事情了,页面竟然是用aspx动态生成的,技术你就不需要研究了,总之,碰到了一个比较小的问题。

    首先,点击下一页的时候,页面是局部刷新的
    在这里插入图片描述
    刷新的同时,捕获了一下发送的请求,是post方式,这个需要留意一下,最要紧的是下面第2张图片和第3张图片。
    在这里插入图片描述
    这张图片中的viewstate
    在这里插入图片描述

    这张图片也有一些奇怪的参数
    在这里插入图片描述

    这些参数都是典型的动态网页参数。

    解决这个问题,还要从源头抓起!

    打开我们要爬取的首页http://yglz.tousu.hebnews.cn/l-1001-5- 第1点需要确定,post的地址经过分析就是这个页面。

    所以这段代码是必备的了,注意下面的post

    response = requests.post("http://yglz.tousu.hebnews.cn/l-1001-5-")
    html = response.content.decode("utf-8")
    

    右键查看源码之后,发现源码中有一些比较重要的隐藏域 里面获取就是我们要的必备信息
    在这里插入图片描述
    没错,这些内容,我们想办法获取到就可以了
    基本步骤

    1. 获取源码
    2. lxml通过xpath解析隐藏域,取值
    import requests
    from lxml import etree  # 从lxml中导入etree
    try:
        response = requests.post("http://yglz.tousu.hebnews.cn/l-1001-5-")
        html = response.content.decode("utf-8")
    except Exception as e:
        print(e)
    
    tree=etree.HTML(html)  # 解析html
    hids = tree.xpath('//input[@type="hidden"]')  # 获取隐藏域
    
    # 声明一个字典,用来存储后面的数据
    common_param = {}
    # 循环取值
    for ipt in hids:
        common_param.update({ipt.get("name"):ipt.get("value")})  # 这个地方可以分开写,应该会很清楚,我就不写了,总之,就是把上面获取到的隐藏域的name属性和value属性都获取到了
    
    

    上面的代码写完之后,其实已经完成了,非常核心的内容了,后面就是继续爬取了
    我们按照post要的参数补充完整其他的参数即可

    import requests
    from lxml import etree  # 从lxml中导入etree
    
    try:
        response = requests.post("http://yglz.tousu.hebnews.cn/l-1001-5-")
        html = response.content.decode("utf-8")
    except Exception as e:
        print(e)
    
    tree=etree.HTML(html)  # 解析html
    
    hids = tree.xpath('//input[@type="hidden"]')
    common_param = {}
    for ipt in hids:
        common_param.update({ipt.get("name"):ipt.get("value")})
    
    ##############################################################
    for i in range(1,691):
        common_param.update({"__CALLBACKPARAM":f"Load|*|{i}",  # 注意这个地方,由于我直接看到了总共有690页数据,所以直接写死了循环次数
                           "__CALLBACKID": "__Page",
                           "__EVENTTARGET":"",
                           "__EVENTARGUMENT":""})
    
    
    

    到这一步,就可以抓取真实的数据了,我在下面的代码中最关键的一些地方加上注释,希望你能看懂

    for i in range(1,691):
        common_param.update({"__CALLBACKPARAM":f"Load|*|{i}",
                           "__CALLBACKID": "__Page",
                           "__EVENTTARGET":"",
                           "__EVENTARGUMENT":""})
    
    
        response = requests.post("http://yglz.tousu.hebnews.cn/l-1001-5-",data=common_param,headers=headers)
        html = response.content.decode("utf-8")
        print("*"*200)
    
        tree = etree.HTML(html)  # 解析html
        divs = tree.xpath('//div[@class="listcon"]')  # 解析列表区域div
        for div in divs:  # 循环这个区域
            try:
            	# 注意下面是通过div去进行的xpath查找,同时加上try方式报错
                shouli = div.xpath('span[1]/p/a/text()')[0]  # 受理单位
                type = div.xpath('span[2]/p/text()')[0].replace("
    ","")  # 投诉类型
                content = div.xpath('span[3]/p/a/text()')[0]  # 投诉内容
                datetime = div.xpath('span[4]/p/text()')[0].replace("
    ","")  # 时间
                status = div.xpath('span[6]/p/text()')[0].replace("
    ","")  # 时间
                one_data = {"shouli":shouli,
                            "type":type,
                            "content":content,
                            "datetime":datetime,
                            "status":status,
                            }
                print(one_data)  # 打印数据,方便存储到mongodb里面
                
            except Exception as e:
                print("内部数据报错")
                print(div)
                continue
        
    

    代码完成,非常爽
    在这里插入图片描述

    最后抓取到了 13765 条数据,官方在我抓取的时候是13790,差了25条数据,没有大的影响~
    在这里插入图片描述

    数据我都存储在了 mongodb里面,关于这个如何使用,请去看我以前的代码吧~~~~

    这些数据,放着以后做数据分析用了。

    https://github.com/wangdezhen/yangguangwenzheng

  • 相关阅读:
    【题解】【BT】【Leetcode】Populating Next Right Pointers in Each Node
    【题解】【BT】【Leetcode】Binary Tree Level Order Traversal
    【题解】【BST】【Leetcode】Unique Binary Search Trees
    【题解】【矩阵】【回溯】【Leetcode】Rotate Image
    【题解】【排列组合】【素数】【Leetcode】Unique Paths
    【题解】【矩阵】【回溯】【Leetcode】Unique Paths II
    【题解】【BST】【Leetcode】Validate Binary Search Tree
    【题解】【BST】【Leetcode】Convert Sorted Array to Binary Search Tree
    第 10 章 判断用户是否登录
    第 8 章 动态管理资源结合自定义登录页面
  • 原文地址:https://www.cnblogs.com/happymeng/p/10153610.html
Copyright © 2011-2022 走看看