- Python爬虫 - 爬取肯德基餐厅信息
- 网页分析
- 背景介绍
- 页面分析
- 撸代码
- 1. URL和参数
- 2. 发起请求
- 3. 持久化存储
- 所有代码
这是我们要爬取的页面
http://www.kfc.com.cn/kfccda/storelist/index.aspx
我们先根据城市查询餐厅信息
选择城市后,可以看到下面的查询结果
- 发现查询前后URL没有发生变化,显然下面的内容是动态加载的
- F12进入开发者工具,点击网络进行抓包,刷新页面,选择XHR,再次选择城市
- 网站非常简洁,一眼就看到了我们需要的数据包,点击查看,发现是post请求
- 点击预览可以看到,我们想要的信息都在这啦
-
多次更换城市名和页数发现XHR包的请求URL不变
-
点击Payload发现,cname代表城市名,pid每次都为空,pageIndex是当前页码,pageSize是每页的信息条数
-
“查询字符串参数”的op是URL中的参数,代表查询方式,即以cname(城市名查询)| keyword(关键字查询)
我们只演示城市名查询方式,关键字查询方式实际上大同小异!
http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=cname
于是定义
post_url请求URL全程不变
city用户输入城市名
pageIndex初始为1,下面循环的时候会改变
pageSize就用10即可
post_url = 'http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=cname' city = input('输入要查询的城市:') data = { 'cname': city, 'pid': '', 'pageIndex': '1', 'pageSize': '10' }2. 发起请求
- 第一次发起请求,获取到信息总条数,再循环遍历所有页
res = requests.post(url=post_url, data=data, headers=headers)
多次更改页数可以观察到,rowcount值一直不变,显然这就是信息总条数
于是便可以获取总页数(pageSize为10的情况下)res_json = json.loads(res.text) row_counts = res_json['Table'][0]['rowcount'] # 记录总条数 page_counts = math.ceil(row_counts / 10) # 总页数,向上取整
- 循环遍历所有页面
观察发现主要数据都在Table1里面,于是我们每次遍历只增加Table1的列表长度pageIndex = 1 # 当前页数 while pageIndex < page_counts: time.sleep(random.random() * 10 % 4) pageIndex += 1 data['pageIndex'] = str(pageIndex) # 改变当前页码 # Table对应的值不变,只需改变Table1的列表长度 res_json['Table1'] += json.loads(requests.post(url=post_url, data=data, headers=headers).text)['Table1']
把最终结果保存到本地,同时又想让数据好看,怎么办呢?
使用json.dumps()可以格式化JSON字符串,注意是字符串!
然后将格式化后的字符串写入.json文件即可
# 保存格式化后的JSON with open('TestDir/KFC_'+city+'.json', 'w', encoding='utf-8') as fp: res_formatted = json.dumps(res_json, indent=4, ensure_ascii=False, sort_keys=False) fp.write(res_formatted)所有代码
import requests import json import time import math import random if __name__ == '__main__': headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36 Edg/96.0.1054.62' } # 参数op=cname表示按城市查询 post_url = 'http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=cname' city = input('输入要查询的城市:') data = { 'cname': city, 'pid': '', 'pageIndex': '1', 'pageSize': '10' } res = requests.post(url=post_url, data=data, headers=headers) # 循环请求所有页 res_json = json.loads(res.text) row_counts = res_json['Table'][0]['rowcount'] # 记录总条数 page_counts = math.ceil(row_counts / 10) # 总页数,向上取整 pageIndex = 1 # 当前页数 while pageIndex < page_counts: time.sleep(random.random() * 10 % 4) pageIndex += 1 data['pageIndex'] = str(pageIndex) # 改变当前页码 # Table对应的值不变,只需改变Table1的列表长度 res_json['Table1'] += json.loads(requests.post(url=post_url, data=data, headers=headers).text)['Table1'] # 保存格式化后的JSON with open('TestDir/KFC_'+city+'.json', 'w', encoding='utf-8') as fp: res_formatted = json.dumps(res_json, indent=4, ensure_ascii=False, sort_keys=False) fp.write(res_formatted) print(res_json) print('Done')
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)