Python 爬虫实战:从 Ajax 到 POST 请求,完整爬取汉堡王门店与产品数据

很多初学爬虫的朋友都会卡在一个点:
页面能看到数据,但用 requests 却抓不到。

这类问题 90% 的原因只有一个:数据不是 HTML 直出,而是 Ajax / POST 接口返回的 JSON。

本文将以 汉堡王中国官网 为例,完整演示:

  • 如何分析 Ajax 接口
  • 如何通过 GET 请求分页爬取所有门店信息
  • 如何通过 POST 请求获取产品数据
  • 如何用 正则从 JS 中反推参数
  • 如何写出健壮、不容易报错的解析逻辑

一、项目目标说明

本次实战分为两个核心目标:

1️⃣ 获取所有门店信息(GET + Ajax)

  • 门店名称
  • 门店地址
  • 门店电话
  • 覆盖所有分页数据

2️⃣ 获取产品信息(POST 请求)

  • 获取不同产品系列
  • 提取每个系列下的产品名称
  • 自动发现系列参数,避免手写

二、门店信息爬取:Ajax 接口分析

2.1 页面数据从哪里来?

门店页面地址:

复制代码
https://www.bkchina.cn/restaurant/index.html

打开浏览器开发者工具 → Network → XHR,你会发现页面并没有直接加载门店 HTML,而是调用了一个 Ajax 接口:

复制代码
https://www.bkchina.cn/restaurant/getMapsListAjax

核心请求参数包括:

参数名 说明
page 页码
storeProvince 省份
storeCity 城市
localSelect 预留参数
search 搜索关键字

👉 这正是爬虫的突破口


2.2 使用 requests 发送 GET 请求

python 复制代码
import requests

page = 1
count = 1

while True:
    url = (
        f"https://www.bkchina.cn/restaurant/getMapsListAjax?"
        f"page={page}&storeProvince=广东省&storeCity=广州市&localSelect=&search="
    )
    res = requests.get(url)
    res_data = res.json()

这里有一个关键点:

  • res.text → 原始字符串
  • res.json() → 自动转为 Python 字典(并处理 Unicode 中文)

2.3 终止循环的正确方式

接口返回的数据结构大致如下:

python 复制代码
{
  "data": {
    "data": [...]
  }
}

当所有数据抓取完成后:

python 复制代码
res_data['data']['data'] == []

所以终止条件可以写成:

python 复制代码
if not res_data['data']['data']:
    break

这是比 try/except 更稳妥的写法


2.4 解析门店信息(字段清洗)

python 复制代码
for i in res_data['data']['data']:
    storeAddress = i['storeAddress'].replace(" ", "")
    storeName = i['storeName']
    storePhone = i['storePhone']

    print(count, storeName, storeAddress, storePhone)
    count += 1

page += 1

📌 小细节很重要:

  • 地址中含有  ,需要清洗
  • 不建议裸 except 吃掉异常

三、产品信息爬取:POST 请求入门

3.1 为什么这里是 POST?

产品接口地址:

复制代码
https://www.bkchina.cn/product/productList

在 Network → Payload 中可以看到:

  • 请求方式:POST
  • 参数:type

这类请求参数不会拼在 URL 上,而是放在请求体中。


3.2 单个系列产品获取

python 复制代码
import requests

url = 'https://www.bkchina.cn/product/productList'
data = {'type': 'season'}

res = requests.post(url, data=data)
res_data = res.json()

返回结果是一个字典,结构类似:

python 复制代码
{
  "季节新品": [
    {"FName": "XX 汉堡"},
    ...
  ]
}

解析方式:

python 复制代码
for series, products in res_data.items():
    for p in products:
        print(p['FName'])

四、批量获取所有产品系列

4.1 手动维护参数(不推荐)

python 复制代码
types = [
    'season', 'ham', 'snack', 'dessert',
    'meats', 'coffee', 'breakfirst', 'happy_meal'
]

循环请求即可:

python 复制代码
for type in types:
    res = requests.post(url, data={'type': type})

❌ 问题是:
参数是前端写死在 JS 中的,后期可能会变。


五、进阶技巧:从 JS 中反推参数(强烈推荐)

5.1 参数真正来源

前端 JS 文件:

复制代码
https://www.bkchina.cn/website/new/js/product.js

我们可以直接请求这个 JS 文件。


5.2 正则提取所有 type 参数

python 复制代码
import re
import requests

js_url = 'https://www.bkchina.cn/website/new/js/product.js'
res = requests.get(js_url)
res_data_str = res.text

types = re.findall("type = '(.*?)'", res_data_str)[1:]
print(types)

📌 使用 非贪婪匹配 (.*?),避免匹配过多内容。


5.3 自动化爬取所有系列产品

python 复制代码
for type in types:
    res = requests.post(url, data={'type': type})
    res_data = res.json()

    for k, v in res_data.items():
        print('系列名:', k)
        if not v:
            continue
        for y in v:
            print(y['FName'])

六、常见坑 & 经验总结

⚠️ 1. data 和 params 不要混用

  • GET → params
  • POST → data

⚠️ 2. 字典取值要防 None

python 复制代码
if v:
    for y in v:
        ...

⚠️ 3. 能不用 try/except 就不用

先判断,再处理,代码更可控


七、总结

通过这个完整案例,你应该已经掌握:

✅ Ajax 接口分析思路

✅ GET 分页爬取技巧

✅ POST 请求参数传递

✅ JSON 数据解析

✅ JS 反向参数提取(核心进阶)

爬虫不是"会 requests 就行",
而是"你能否像前端一样理解数据流向"。


如果这篇文章对你有帮助,

欢迎 点赞 👍 + 收藏 ⭐ + 关注我,后续我会继续拆解更多真实网站的爬虫实战案例 🚀

相关推荐
TheSumSt2 小时前
Python丨课程笔记Part2:方法论进阶部分
开发语言·笔记·python
知远同学2 小时前
使用virtualenv 和 anaconda 创建管理虚拟环境的区别
python
山沐与山2 小时前
【设计模式】Python状态模式:从入门到实战
python·设计模式·状态模式
Swizard2 小时前
别让你的密钥在互联网上“裸奔”!用 python-dotenv 优雅管理你的敏感配置
python
无心水2 小时前
【Stable Diffusion 3.5 FP8】8、生产级保障:Stable Diffusion 3.5 FP8 伦理安全与问题排查
人工智能·python·安全·docker·stable diffusion·ai镜像开发·镜像实战开发
深蓝海拓3 小时前
PySide6从0开始学习的笔记(十八) MVC(Model-View-Controller)模式的图形渲染体系
笔记·python·qt·学习·pyqt
一招定胜负3 小时前
杂记:cv2.imshow显示中文乱码解决过程
python·opencv
唐叔在学习3 小时前
Pyinstaller进阶之构建管理大杀器-SPEC文件
后端·python·程序员
爱吃山竹的大肚肚3 小时前
在Java中,从List A中找出List B没有的数据(即求差集)
开发语言·windows·python