欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Python爬虫 | 对广州市*数据统一开放平台数据的爬取

程序员文章站 2022-03-26 11:35:35
...

Python爬虫 | 对广州市*数据统一开放平台数据的爬取

简单爬虫

本次爬虫演示的是对 广州市*数据统一开放平台 数据的爬取

网页分析

我们先到url=’ http://data.gz.gov.cn/odweb/dev/developer/serviceList.htm’
这里,从左边下载排行随便点击一个链接,我点击的是’广州市各区幼儿园一览表’
url=’ http://data.gz.gov.cn/odweb/catalog/catalogDetail.htm?cata_id=29354’

Python爬虫 | 对广州市*数据统一开放平台数据的爬取

跳到了一个新的页面,而我们要的是数据,理所当然,点击’数据详细’

Python爬虫 | 对广州市*数据统一开放平台数据的爬取

可以看到,下面这个框框发生了变化,这里是使用的是ajax,ajax最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容,具体内容可以自行百度,这里就不详细讲解

Python爬虫 | 对广州市*数据统一开放平台数据的爬取

一般这种ajax都会有一个json文件用来显示数据,所以我们在浏览器按’F12’打开开发者工具,这里我使用的是chrome浏览器,点击’F5’刷新网页
又回到了刚刚的页面,继续点击’数据详细’

Python爬虫 | 对广州市*数据统一开放平台数据的爬取

在下面这个窗口寻找我们要的json文件
怎么找?先随便点击一个文件,会弹出这样的窗口

Python爬虫 | 对广州市*数据统一开放平台数据的爬取

然后从左边一个一个文件慢慢点击,直到右边显示json格式的数据,
如下图所示

Python爬虫 | 对广州市*数据统一开放平台数据的爬取

当然,你也可以使用网页自带的筛选器,这里json文件type是xhr,我记得也有script的,如有其他的,请大佬多多补充

Python爬虫 | 对广州市*数据统一开放平台数据的爬取
再点击headers,发现requests url有点奇怪
http://data.gz.gov.cn/dataanaly/data/CatalogDetail.do?method=GetDataListForGrid
一般不是都在后面加一堆数字或乱码吗??
因为url都会带有一些参数,
比如’http://data.gz.gov.cn/odweb/catalog/catalogDetail.htm?cata_id=29354
cata_id代表数据的id
而这里的url像一般登录后的url
Python爬虫 | 对广州市*数据统一开放平台数据的爬取

在另一个页面输入该url后,会出现这个页面

Python爬虫 | 对广州市*数据统一开放平台数据的爬取
不对啊,这里不应该显示json格式的数据吗?
回到刚才的使用开发者工具的页面,headers拉到最下面,发现了个form data,这个很关键,是本次案例的重点-提交post

Python爬虫 | 对广州市*数据统一开放平台数据的爬取
我们可以使用下面代码,检验是否能输出json格式数据

import requests

headers = {
        'Host': 'data.gz.gov.cn',
        'Referer': 'http://data.gz.gov.cn/odweb/catalog/catalogDetail.htm?cata_id=29354',
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36'
        }
login_url = 'http://data.gz.gov.cn/dataanaly/data/catalogDataList.htm?cata_id=29354'
post_url = 'http://data.gz.gov.cn/dataanaly/data/CatalogDetail.do?method=GetDataListForGrid'
session = requests.Session()
post_data = {
        'cata_id': 29354,
        'conf_type': 2,
        'where': [],
        '_search': 'false',
        'rows': 10,
        'page': 1,
        'sidx': '',
        'sord': 'asc',
        }
response = session.post(post_url, data=post_data, headers=headers)       
print(response.status_code)
print(response.text)

Python爬虫 | 对广州市*数据统一开放平台数据的爬取
成功了!????
到这里,我们的分析就结束了,接下来就是代码时间

爬虫代码

在上面的代码中,post_data中是和开发者工具中form data里面的数据一一对应的,不过有一些数据不会影响,重复实验后,代码可以精简为

post_data = {
        'cata_id': 29354,
        'page': 1,  
        }

cata_id’代表的是数据id号,这里是代表’广州市各区幼儿园一览表’的数据,
'page’代表页数
模拟登录也就是向服务器post一些数据,然后返回数据或者一个页面,具体也可以自行百度哈

我编写了一个类DataOfGov,里面包含了login(模拟登录),json_text(解析json),save(保存)

import requests
import json
import time
 

class DataOfGov(object):
    def __init__(self):
        self.headers = {
        'Host': 'data.gz.gov.cn',
        'Referer': 'http://data.gz.gov.cn/odweb/catalog/catalogDetail.htm?cata_id=29354',
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36'
        }
        self.login_url = 'http://data.gz.gov.cn/dataanaly/data/catalogDataList.htm?cata_id=29354'
        self.post_url = 'http://data.gz.gov.cn/dataanaly/data/CatalogDetail.do?method=GetDataListForGrid'
        self.session = requests.Session()

 
    def login(self,cata_id,page):
        post_data = {
        'cata_id': cata_id,
        'conf_type': 2,
        'where': [],
        '_search': 'false',
        'rows': 10,
        'page': page,
        'sidx': '',
        'sord': 'asc',
        }
        response = self.session.post(self.post_url, data=post_data, headers=self.headers)       
        print(page)
        print(response.status_code)
        
        for datas in self.json_text(response.text):
            self.save(datas)
    
    def json_text(self,text):
        js=json.loads(text)      
        for rows in js['rows']:
            valuelist=[]
            for key,value in rows.items():
                print(value,end=';')
                valuelist.append(value)
            print('')
            yield(valuelist)
    def save(self,datas):
        path=r'E:\1learn\csdn\govofdata.txt'    
        with open(path,'a') as f:
            for data in datas:
                f.write(data)
                f.write(';')
            f.write('\n')
            f.close()

if __name__ == "__main__":
    starttime=time.time()
    cata_id=29354
    main = DataOfGov()
    titlelist=['年份','行政区域','联系电话','办园性质','更新时间','地址','幼儿园名称']       
    main.save(titlelist)
    for page in range(1,11):
        login=main.login(cata_id,page)
    endtime=time.time()
    print('total time:',endtime-starttime)

    

在save()函数当中,我把保存到了一个txt,然后可以把txt转换成excel文件。
我是用分号分开的,所以记得点击’分号’按钮
Python爬虫 | 对广州市*数据统一开放平台数据的爬取

Python爬虫 | 对广州市*数据统一开放平台数据的爬取
PS:文章写得有些粗糙,如有问题请各位大佬多多指教