Python爬虫 - 爬取肯德基餐厅信息

Python爬虫 - 爬取肯德基餐厅信息,第1张

Python爬虫 - 爬取肯德基餐厅信息 Python爬虫 - 爬取肯德基餐厅信息

文章目录
  • Python爬虫 - 爬取肯德基餐厅信息
    • 网页分析
      • 背景介绍
      • 页面分析
    • 撸代码
      • 1. URL和参数
      • 2. 发起请求
      • 3. 持久化存储
    • 所有代码

网页分析 背景介绍

这是我们要爬取的页面
http://www.kfc.com.cn/kfccda/storelist/index.aspx
我们先根据城市查询餐厅信息
选择城市后,可以看到下面的查询结果

页面分析
  1. 发现查询前后URL没有发生变化,显然下面的内容是动态加载的
  2. F12进入开发者工具,点击网络进行抓包,刷新页面,选择XHR,再次选择城市
  3. 网站非常简洁,一眼就看到了我们需要的数据包,点击查看,发现是post请求
  4. 点击预览可以看到,我们想要的信息都在这啦
撸代码 1. URL和参数
  1. 多次更换城市名和页数发现XHR包的请求URL不变

  2. 点击Payload发现,cname代表城市名,pid每次都为空,pageIndex是当前页码,pageSize是每页的信息条数

  3. “查询字符串参数”的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. 发起请求
  1. 第一次发起请求,获取到信息总条数,再循环遍历所有页
    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) # 总页数,向上取整
    
  2. 循环遍历所有页面
    观察发现主要数据都在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']
    
3. 持久化存储

把最终结果保存到本地,同时又想让数据好看,怎么办呢?
使用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')

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5689394.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存