实战爬虫抓取接口数据含踩坑解析

发布时间: 2025年12月30日
摘要信息
招标单位
招标编号
招标估价
招标联系人
招标代理机构
代理联系人
报名截止时间
投标截止时间
关键信息
招标详情
下文中****为隐藏内容,仅对千里马会员开放,如需查看完整内容请 或 拨打咨询热线: 400-688-2000

本文通过一次完整实战,演示如何使用 Python + requests ****政府采购网公告列表数据,并重点分析 JSON 结构解析中常见的 TypeError 问题。

一、需求背景

在日常学习爬虫时,****种场景:

页面是 列表页
数据不是写在 HTML 中
而是通过 XHR 接口动态加载

****政府采购网的公告列表页:

http://www.ccgp-hunan.****.cn/page/notice/more.jsp?noticeTypeID=prcmNotices

页面滚动 / 翻页时,实际请求的是一个接口。

二、定位真实接口(关键一步) 1 打开开发者工具
F12 → Network
选择 Fetch / XHR
翻页或刷新页面

你会发现不断请求:

getNoticeList4Web.do 2 接口核心信息

请求地址

http://www.ccgp-hunan.****.cn/mvc/getNoticeList4Web.do

请求方式

POST

Content-Type

application/x-www-form-urlencoded 3 请求参数分析(表单数据)

从 Network → Payload 可以看到完整参数:

nType: prcmNoticespType:prcmPrjName:prcmItemCode:prcmOrgName:startDate: 2025-01-01endDate: 2025-12-28prcmPlanNo:page: 1pageSize: 18

重点: 这是 form 表单请求,不是 JSON!

三、返回数据结构解析(重点)

接口返回的是一个 JSON,大致结构如下:

{ "total": 4750, "hzMap": "rows": [ { "NOTICE_TITLE": "**省XX项目公开招标公告", "NEWWORK_DATE": "2025-12-25", "PRCM_MODE_NAME": "公开招标" }, ... ]}

重点字段说明:

字段 含义
total 总数据量
rows 当前页的数据列表
NOTICE_TITLE 公告标题
NEWWORK_DATE 发布时间
四、原始代码 问题分析

你一开始的核心代码是:

for k, v in res_data.items(): for y in v: print(y) 报错原因

接口返回的数据中:

res_data["total"] = 4750

于是代码等价于:

for y in 4750: ...

直接触发:

TypeError: "int" object is not iterable

int 不能被 for 遍历

五、正确的解析思路(核心)

我们真正需要的只有:

res_data["rows"]

因为它才是 列表(list)

六、完整可运行示例代码(推荐版本) import requests
url = "http://www.ccgp-hunan.****.cn/mvc/getNoticeList4Web.do"
page = 1
while True: para = { "nType": "prcmNotices", "pType": "", "prcmPrjName": "", "prcmItemCode": "", "prcmOrgName": "", "startDate": "2025-01-01", "endDate": "2025-12-28", "prcmPlanNo": "", "page": page, "pageSize": 18 }
response = requests.post(url, data=para) res_data = response.json()
rows = res_data.get("rows")
# 如果没有数据,说明翻页结束 if not rows: print("数据抓取完成") break
print(f"===== 第 {page} 页 =====")
for item in rows: title = item.get("NOTICE_TITLE") date = item.get("NEWWORK_DATE") mode = item.get("PRCM_MODE_NAME")
print(date, mode, title)
page += 1 七、代码关键点解析 1 为什么用 data=para

因为接口是:

Content-Type: application/x-www-form-urlencoded

如果写成:

json=para

会直接拿不到数据。

2 为什么只遍历 rows
rows = res_data.get("rows")
rows 是 list
每一项是 dict
正好对应公告数据
3 为什么要判断 rows 是否为空 if not rows: break

这是 分页爬虫的标准写法,用于自动停止。

八、常见坑位总结(必看) 坑 1:对 int / None 直接 for
for y in res_data["total"]:

正确: 先判断类型 or 直接定位 list 字段

坑 2:把 form 请求当 JSON 请求
requests.post(url, json=para) #

正确:

requests.post(url, data=para) 坑 3:无脑遍历 res_data.items()

接口返回结构一定要 先 print 看清楚

九、可以继续扩展的方向
保存为 CSV / Excel
写入 MySQL / SQLite
增加异常重试
多进程抓取
解析公告详情页
十、总结

爬虫的本质不是写代码 而是 看接口 + 读数据结构 + 精准解析

这次案例里最核心的一点就是:

不要假设接口返回的数据结构,一定要先看清楚 JSON


招标进度跟踪
2025-12-30
招标公告
实战爬虫抓取接口数据含踩坑解析
当前信息
招标项目商机
暂无推荐数据
400-688-2000
欢迎来电咨询~