168 lines
3.4 KiB
Markdown
168 lines
3.4 KiB
Markdown
|
|
# 中国政府采购网抓取指南
|
||
|
|
|
||
|
|
## 当前实现概述
|
||
|
|
|
||
|
|
当前 `crawler/ccgp_crawler.py` 已不是单一搜索接口爬虫,而是“搜索接口 + 栏目页回退 + 诊断输出”的组合实现。
|
||
|
|
|
||
|
|
## 当前抓取逻辑
|
||
|
|
|
||
|
|
### 第一层:搜索接口
|
||
|
|
|
||
|
|
优先请求:
|
||
|
|
|
||
|
|
- `https://search.ccgp.gov.cn/bxsearch`
|
||
|
|
|
||
|
|
### 第二层:回退到公告栏目扫描
|
||
|
|
|
||
|
|
当搜索接口出现以下情况时:
|
||
|
|
|
||
|
|
- `频繁访问`
|
||
|
|
- `403 Forbidden`
|
||
|
|
- `Internal Server Error`
|
||
|
|
- 其他阻断页
|
||
|
|
|
||
|
|
爬虫会自动回退到公告栏目页扫描,例如:
|
||
|
|
|
||
|
|
- 地方公告 `dfgg`
|
||
|
|
- 中央公告 `zygg`
|
||
|
|
- 公开招标、成交公告、竞争性磋商、竞争性谈判、询价等栏目
|
||
|
|
|
||
|
|
然后再按关键词在标题和正文里过滤。
|
||
|
|
|
||
|
|
### 第三层:诊断输出
|
||
|
|
|
||
|
|
如果仍未得到有效结果,会把现场诊断保存到:
|
||
|
|
|
||
|
|
- `data/ccgp_probe_*.json`
|
||
|
|
|
||
|
|
## 入口用法
|
||
|
|
|
||
|
|
### 直接运行
|
||
|
|
|
||
|
|
```bash
|
||
|
|
python crawler/ccgp_crawler.py
|
||
|
|
```
|
||
|
|
|
||
|
|
### 通过主流程运行
|
||
|
|
|
||
|
|
```bash
|
||
|
|
python main.py --mode crawl --sources ccgp --ccgp-keywords "信控,绿波"
|
||
|
|
python main.py --mode full --sources ccgp
|
||
|
|
```
|
||
|
|
|
||
|
|
### 在代码里调用
|
||
|
|
|
||
|
|
```python
|
||
|
|
from crawler.ccgp_crawler import CCGPCrawler
|
||
|
|
|
||
|
|
crawler = CCGPCrawler()
|
||
|
|
results = crawler.crawl_and_save(
|
||
|
|
keywords=["交通管理", "信控"],
|
||
|
|
max_per_keyword=20,
|
||
|
|
output_dir="./data",
|
||
|
|
save_to_rag=False,
|
||
|
|
)
|
||
|
|
```
|
||
|
|
|
||
|
|
## 需要注意的当前行为
|
||
|
|
|
||
|
|
### `crawl_and_save` 默认不自动入库
|
||
|
|
|
||
|
|
当前 `CCGPCrawler.crawl_and_save()` 的默认参数是:
|
||
|
|
|
||
|
|
```python
|
||
|
|
save_to_rag=False
|
||
|
|
```
|
||
|
|
|
||
|
|
也就是说:
|
||
|
|
|
||
|
|
- 独立运行 `crawler/ccgp_crawler.py` 时,默认只保存 JSON / probe
|
||
|
|
- 通过 `main.py --mode crawl/full` 运行时,会由 `main.py` 的统一 RAG 流程入库
|
||
|
|
|
||
|
|
## 数据格式
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"title": "项目标题",
|
||
|
|
"url": "详情页URL",
|
||
|
|
"date": "2026-04-29",
|
||
|
|
"project_type": "公开招标公告",
|
||
|
|
"region": "江西",
|
||
|
|
"keyword": "交通管理",
|
||
|
|
"source": "中国政府采购网",
|
||
|
|
"crawl_time": "2026-04-29 16:44:22",
|
||
|
|
"content": "正文文本"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## 典型输出文件
|
||
|
|
|
||
|
|
- 成功结果:`ccgp_results_*.json`
|
||
|
|
- 失败或限流诊断:`ccgp_probe_*.json`
|
||
|
|
|
||
|
|
## 适合的关键词
|
||
|
|
|
||
|
|
当前实践中,更容易命中的通常是:
|
||
|
|
|
||
|
|
- `交通管理`
|
||
|
|
- `交通`
|
||
|
|
- `电子警察`
|
||
|
|
- `视频专网`
|
||
|
|
- `信号灯`
|
||
|
|
- `信控`
|
||
|
|
- `绿波`
|
||
|
|
|
||
|
|
说明:
|
||
|
|
|
||
|
|
- `交通管理` 一类宽词通常命中更多
|
||
|
|
- `信控 / 绿波` 一类稀疏词,容易出现“搜索接口被封 + 栏目近几页无命中”的情况
|
||
|
|
|
||
|
|
## 与向量库的关系
|
||
|
|
|
||
|
|
如果你要把抓取结果写入向量库,有两种方式:
|
||
|
|
|
||
|
|
### 方式一:走主流程
|
||
|
|
|
||
|
|
```bash
|
||
|
|
python main.py --mode crawl --sources ccgp
|
||
|
|
```
|
||
|
|
|
||
|
|
### 方式二:手动调用
|
||
|
|
|
||
|
|
```python
|
||
|
|
crawler.save_to_vectordb(results)
|
||
|
|
```
|
||
|
|
|
||
|
|
## 常见问题
|
||
|
|
|
||
|
|
### 搜索接口报错,但代码仍有结果
|
||
|
|
|
||
|
|
说明回退逻辑生效了,这是当前实现的正常行为。
|
||
|
|
|
||
|
|
### 搜索接口报错,且没有结果
|
||
|
|
|
||
|
|
检查:
|
||
|
|
|
||
|
|
1. 关键词是否过窄
|
||
|
|
2. 当前栏目近几页是否真的没有相关公告
|
||
|
|
3. 诊断文件 `ccgp_probe_*.json` 中的 `listing_fallback_scan` 信息
|
||
|
|
|
||
|
|
### 为什么文档里不再把 `bxsearch` 当成稳定方案
|
||
|
|
|
||
|
|
因为当前实测中,`bxsearch` 在部分环境下会返回:
|
||
|
|
|
||
|
|
- 限频页
|
||
|
|
- 403
|
||
|
|
- 500
|
||
|
|
|
||
|
|
所以现有文档只把它视为“优先尝试”,不是“唯一可靠链路”。
|
||
|
|
|
||
|
|
## 已删除的旧说明
|
||
|
|
|
||
|
|
以下说法已不再准确:
|
||
|
|
|
||
|
|
- 政府采购网抓取只依赖 `bxsearch`
|
||
|
|
- 搜索结果为空通常只是关键词问题
|
||
|
|
- 独立脚本默认就会自动写入向量库
|
||
|
|
|