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

    xiaoxiao2023-10-17  224

    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’

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

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

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

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

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

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

    再点击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

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

    不对啊,这里不应该显示json格式的数据吗? 回到刚才的使用开发者工具的页面,headers拉到最下面,发现了个form data,这个很关键,是本次案例的重点-提交post

    我们可以使用下面代码,检验是否能输出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)

    成功了!? 到这里,我们的分析就结束了,接下来就是代码时间

    爬虫代码

    在上面的代码中,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文件。 我是用分号分开的,所以记得点击’分号’按钮

    PS:文章写得有些粗糙,如有问题请各位大佬多多指教

    最新回复(0)