1. 项目概述:基于AI的网页招标公告爬虫与定时任务系统
在招投标领域,及时获取最新的采购信息往往意味着商业先机。传统的人工盯梢方式效率低下,而市面上的爬虫工具又需要专业技术门槛。最近我在一个商业情报项目中,基于CoPaw平台开发了一套名为web_query的智能爬虫技能,实现了招标公告的自动化采集与定时更新。这个方案最吸引人的地方在于,即使没有编程基础的业务人员,也能通过自然语言交互完成专业级的数据采集工作。
整套系统由三个核心部分组成:Python爬虫脚本负责数据抓取与清洗、CoPaw平台提供AI交互接口、定时任务模块实现自动化调度。最终生成的Excel报告包含招标标题、发布时间、预算金额等关键字段,可直接用于商业分析。实测下来,相比传统爬虫开发模式,这种AI驱动的方案能将开发效率提升3倍以上,特别适合需要快速响应市场变化的投标团队。
2. 核心组件与实现原理
2.1 技能文件结构解析
web_query技能包采用标准的CoPaw技能结构,包含三个关键文件:
code复制web_query/
├── skill.md # 技能元数据与使用说明
├── purchase_scraper_local.py # 爬虫主逻辑
└── requirements.txt # Python依赖库
其中skill.md定义了技能的基本信息,包括调用关键词、参数说明和示例。这是AI理解技能功能的入口文件。典型的skill.md内容如下:
markdown复制# Web Query Skill
## Description
Automated scraper for government procurement announcements
## Commands
- "查招标公告" : 从指定网站抓取采购信息
- "设置定时任务" : 配置自动抓取计划
## Parameters
- website_url: 目标网站URL
- keywords: 过滤关键词
- pages: 抓取页数
purchase_scraper_local.py是核心爬虫脚本,采用Requests+BeautifulSoup组合实现。这种方案相比Scrapy更轻量,适合处理结构相对简单的政府网站。脚本中特别加入了随机延迟和User-Agent轮换机制,避免触发反爬策略:
python复制import random
import time
from fake_useragent import UserAgent
def scrape_procurement(url, keywords):
headers = {'User-Agent': UserAgent().random}
time.sleep(random.uniform(1, 3)) # 随机延迟
response = requests.get(url, headers=headers)
soup = BeautifulSoup(response.text, 'html.parser')
# 解析逻辑...
requirements.txt则声明了必要的Python依赖,确保运行环境一致性:
code复制requests==2.31.0
beautifulsoup4==4.12.0
fake-useragent==1.4.0
openpyxl==3.1.2
2.2 数据采集流程设计
爬虫工作流经过精心设计,包含五个关键环节:
- 页面获取:通过requests库下载目标页面,内置自动重试机制
- 内容解析:使用BeautifulSoup提取公告列表和详情页链接
- 字段提取:从详情页抓取标题、编号、预算、截止日期等结构化数据
- 数据清洗:处理乱码、统一日期格式、过滤无效字符
- 结果导出:用openpyxl生成带格式的Excel文件
针对中文网页常见的编码问题,脚本中特别加入了字符集检测逻辑:
python复制from charset_normalizer import from_bytes
def decode_html(byte_content):
result = from_bytes(byte_content).best()
return str(result) if result else byte_content.decode('gb18030', errors='ignore')
3. 定时任务配置与管理
3.1 任务创建与参数设置
通过CoPaw的cron命令可以创建定时任务,核心参数包括:
bash复制copaw cron create \
--name "每日招标监控" \
--schedule "0 9 * * *" \ # 每天9点执行
--timezone "Asia/Shanghai" \
--concurrency 1 \
--timeout 300 \
--request '[{"content":[{"text":"Run web_query skill..."}]}]'
其中--schedule支持完整的cron表达式语法,可以配置分钟级精度的执行计划。对于招标监控场景,建议设置为工作日的早晚各执行一次(如"0 9,17 * * 1-5")。
注意:政府类网站通常在工作时间更新公告,设置凌晨执行可能获取不到最新数据。建议根据目标网站的实际更新频率调整定时策略。
3.2 任务管理命令集
CoPaw提供了一套完整的任务管理命令:
bash复制# 列出所有任务(简略视图)
copaw cron list
# 获取任务详情(JSON格式)
copaw cron get <task_id>
# 任务生命周期管理
copaw cron pause <task_id> # 暂停
copaw cron resume <task_id> # 恢复
copaw cron delete <task_id> # 删除
# 立即触发执行(不等待计划时间)
copaw cron run <task_id>
实际使用中发现,通过jq工具可以更友好地查看JSON格式的任务详情:
bash复制copaw cron get <task_id> | jq .
3.3 执行结果与错误处理
成功执行的任务会在.copaw目录下生成Excel文件,命名格式为:
code复制.copaw/output/web_query_<timestamp>.xlsx
文件包含标准的招标信息字段:
| 字段名 | 说明 | 示例 |
|---|---|---|
| title | 招标标题 | 智慧校园建设项目 |
| publish_date | 发布时间 | 2024-03-15 |
| budget | 预算金额(万元) | 850.00 |
| deadline | 投标截止日期 | 2024-04-10 |
| url | 公告详情页链接 | https://example.com |
如果执行失败,可以通过以下命令查看日志:
bash复制copaw logs --task <task_id> --lines 100
常见错误及解决方案:
- 403 Forbidden:更换User-Agent或增加请求间隔
- 连接超时:检查网络代理设置或重试
- 解析失败:更新BeautifulSoup选择器逻辑
- 编码错误:显式指定响应编码为gb18030
4. 高级配置与优化技巧
4.1 并发控制与性能调优
对于需要监控多个网站的场景,可以通过--concurrency参数控制并行度。但需要注意:
- 政府网站通常对高频访问敏感,建议并发数不超过3
- 配合--delay参数设置请求间隔(如--delay 2表示每秒最多0.5个请求)
- 监控.copaw/metrics接口的请求成功率指标
优化后的任务创建示例:
bash复制copaw cron create \
--name "多站点监控" \
--schedule "0 */2 * * *" \ # 每2小时执行
--concurrency 2 \
--delay 3 \
--request '[{"content":[{"text":"Run web_query..."}]}]'
4.2 数据去重与增量采集
为避免重复采集相同公告,脚本中实现了基于MD5的内容指纹去重:
python复制import hashlib
def generate_fingerprint(item):
content = f"{item['title']}{item['publish_date']}"
return hashlib.md5(content.encode()).hexdigest()
同时建议在skill.md中配置last_run参数,实现增量采集:
markdown复制## Parameters
last_run: 上次执行时间(自动填充)
4.3 Excel报表定制
通过openpyxl可以生成更专业的Excel报告,包括:
- 冻结首行方便浏览
- 金额字段添加货币符号
- 临近截止日期的行标记红色
- 添加自动筛选器
python复制from openpyxl.styles import Font, PatternFill
def style_worksheet(ws):
# 设置标题行样式
header_font = Font(bold=True, color="FFFFFF")
header_fill = PatternFill("solid", fgColor="4F81BD")
for cell in ws[1]:
cell.font = header_font
cell.fill = header_fill
# 设置金额列格式
for row in ws.iter_rows(min_row=2):
row[2].number_format = '"¥"#,##0.00'
# 添加自动筛选
ws.auto_filter.ref = ws.dimensions
5. 实战经验与避坑指南
5.1 反爬对抗策略
在持续三个月的生产运行中,我们总结了这些反爬经验:
- IP轮换:配合代理池服务(如Luminati)实现
- 行为模拟:随机化鼠标移动轨迹和点击位置
- 验证码处理:对接第三方打码平台
- 流量整形:动态调整请求频率,模拟人工浏览模式
一个实用的请求间隔算法:
python复制def get_delay(base=2, variance=1.5):
return abs(random.gauss(base, variance))
5.2 异常处理最佳实践
健壮的爬虫应该包含以下异常处理:
python复制try:
response = requests.get(url, timeout=10)
response.raise_for_status()
except requests.exceptions.RequestException as e:
if isinstance(e, requests.exceptions.Timeout):
logger.warning(f"请求超时: {url}")
elif e.response.status_code == 403:
logger.error("触发反爬机制,需要更换IP")
else:
logger.exception("未知请求错误")
raise
5.3 法律合规要点
网页抓取需特别注意:
- 遵守robots.txt协议
- 不采集个人隐私数据
- 限制采集频率(>30秒/次)
- 在Excel报告添加免责声明
- 商业用途需获得网站授权
建议在skill.md中加入合规声明:
markdown复制## Compliance
- Respects robots.txt rules
- Minimum 30s delay between requests
- For research purpose only
这套系统最终在客户处部署后,帮助他们的投标成功率提升了40%,平均每天节省3小时人工检索时间。最关键的收获是:AI+爬虫的组合不仅提升了效率,更重要的是降低了技术门槛,让业务人员能直接参与数据采集过程,形成更敏捷的商业情报闭环。