5.3 做一个爬虫
目标:掌握「分析网页结构 → 写脚本 → 增量抓取 → 数据落地」的流程,让 AI 成为你的数据抓手。
爬虫是数据获取的重要手段,无论是竞品分析、内容聚合还是市场研究,都离不开自动化数据抓取。这个项目将教会你如何分析网页、编写 Python 脚本、处理数据并持久化存储。
🎯 成品要求
- 针对指定站点抓取所需字段,支持增量更新(不重复抓取)
- 把结果写入 CSV/数据库/飞书多维表格等外部系统
- 有日志输出,遇到失败能定位原因
- 有基本的容错机制(限速、重试)
🧰 准备工作
1. 工具选择
- Cursor/Trae + Claude Code:支持终端运行 Python
- Python 环境:本地 Python 3.10+,或使用 Replit/CodeSandbox 提供的在线环境
2. 目标站点选择
练习站点建议(选择结构清晰、无反爬的站点):
- Notta 博客 :技术博客,结构简单
- Airtable 社区 :论坛类内容
- Product Hunt :产品信息
- 你自己关注的垂直领域网站
注意事项:
- 检查
robots.txt(如https://example.com/robots.txt),遵守爬取规则 - 不要爬取需要登录的内容(涉及法律风险)
- 控制请求频率,避免给服务器造成压力
3. 数据落地方式
选择一个你熟悉的存储方式:
- CSV 文件:最简单,适合小数据量
- Notion 数据库:可视化好,适合个人使用
- 飞书多维表格:团队协作,支持自动化
- Airtable:功能强大,有 API
- 数据库(如 SQLite、PostgreSQL):适合大数据量和复杂查询
🛠️ 实践步骤
步骤 1:勘察页面结构
1.1 打开目标网页
以 Notta 博客为例:https://www.notta.ai/en/blog
1.2 使用浏览器开发者工具
- 右键页面 → 点击「检查」(或按
F12) - 点击左上角的「选择元素」图标(或
Ctrl+Shift+C) - 鼠标悬停在文章卡片上,查看 HTML 结构
1.3 定位关键元素
找到包含文章信息的容器,通常是:
<div class="article-card">
<h2>文章标题</h2>
<a href="/blog/article-slug">链接</a>
<span class="tag">标签</span>
<time>2025-01-15</time>
<p class="excerpt">摘要内容...</p>
</div>复制这段 HTML 给 AI,帮助它理解页面结构。
1.4 检查分页机制
- 是否有「下一页」按钮?
- URL 是否包含页码参数(如
?page=2)? - 是否使用无限滚动加载?
步骤 2:撰写 Prompt
完整示例 Prompt:
写一个 Python 爬虫,抓取 https://www.notta.ai/en/blog 的所有文章信息:
## 目标字段
- title:文章标题
- url:文章完整链接(需要拼接域名)
- tags:标签列表(可能有多个,用逗号分隔)
- published_date:发布日期(格式化为 YYYY-MM-DD)
- excerpt:文章摘要
## 技术要求
- 使用 requests + BeautifulSoup
- 支持分页抓取(检测"下一页"按钮,直到没有下一页为止)
- 每次请求间隔 3 秒,避免被封
- 遇到 4xx/5xx 错误自动重试 3 次
- 添加合适的 User-Agent 头部
## 数据存储
- 保存到 data/notta_blog.csv
- 每次运行只抓取新增文章(用 url 作为唯一标识)
- 如果 CSV 已存在,读取已有的 url 列表,跳过重复内容
## 日志要求
- 打印当前抓取进度(第 X 页 / 共 Y 篇文章)
- 记录失败的请求(URL + 错误原因)
- 最后输出总结(新增 X 篇,跳过 Y 篇,失败 Z 篇)
请生成完整的可运行代码。Prompt 编写技巧:
- 字段要具体:不要只说”抓取文章”,而要列出具体字段
- 容错要明确:说明遇到异常如何处理
- 增量抓取:避免重复抓取浪费时间
步骤 3:运行与调试
3.1 初次运行
# 安装依赖
pip install requests beautifulsoup4 pandas
# 运行脚本
python crawl_notta.py3.2 常见问题排查
| 症状 | 可能原因 | 排查思路 | 解决方案 |
|---|---|---|---|
| 403 / 429 错误 | 被识别为爬虫或请求过快 | 检查 User-Agent、请求频率 | 增加 User-Agent 头部;限速改为 5-10 秒;使用代理 IP |
| 数据为空 | 选择器不匹配 | 打印 HTML 源码,检查实际结构 | 用浏览器复制实际的 class/id;检查是否 JS 渲染 |
| 日期格式错误 | 不同语言的日期格式 | 打印原始日期字符串 | 使用 dateutil.parser 或正则表达式 |
| 编码乱码 | 网页编码不是 UTF-8 | 检查响应头 Content-Type | response.encoding = 'utf-8' 或用 chardet 检测 |
| 分页失效 | 下一页选择器错误 | 打印下一页 URL | 检查”下一页”按钮的 HTML 结构,可能是相对路径 |
调试技巧:
# 打印 HTML 源码,检查选择器
print(soup.prettify()[:500])
# 逐步验证选择器
articles = soup.find_all('div', class_='article-card')
print(f'找到 {len(articles)} 篇文章')
for article in articles[:3]: # 只看前 3 个
print(article.find('h2').text.strip())
# 检查请求是否成功
print(f'状态码: {response.status_code}')
print(f'响应头: {response.headers}')步骤 4:做一个可视化界面(可选)
让爬虫更友好的方式是加一个简单的 Web 界面。
方案 1:用 Streamlit(最简单)
让 AI 基于现有脚本生成 Streamlit 界面:
请把这个爬虫脚本改造成 Streamlit 应用:
## 界面需求
- 输入框:目标 URL、最大页数
- 按钮:开始抓取、停止、导出 CSV
- 进度条:显示当前抓取进度
- 表格:实时展示已抓取的数据
- 日志区域:滚动显示运行日志
## 功能要求
- 点击「开始」后在后台运行爬虫
- 支持随时停止
- 抓取完成后可下载 CSV运行:
pip install streamlit
streamlit run app.py方案 2:用 FastAPI + HTMX(适合想学后端的人)
更复杂但功能更强,参考 5.5 后端服务 的实现方式。
步骤 5:自动化与数据落地
5.1 写入飞书多维表格
Prompt 示例:
请修改爬虫脚本,把数据写入飞书多维表格:
## 飞书配置
- App ID: xxx
- App Secret: xxx
- 表格 Token: xxx
- 字段映射:title → 标题字段,url → 链接字段,等等
## 技术要求
- 使用飞书开放平台 Python SDK
- 每抓取 10 条批量写入一次
- 写入前检查 URL 是否已存在,避免重复
- 失败时记录日志但继续执行安装飞书 SDK:
pip install lark-oapi5.2 定时执行
方式一:crontab(Linux/Mac)
# 编辑定时任务
crontab -e
# 每天早上 9 点执行
0 9 * * * /usr/bin/python3 /path/to/crawl_notta.py >> /path/to/crawl.log 2>&1方式二:GitHub Actions
创建 .github/workflows/crawler.yml:
name: Daily Crawler
on:
schedule:
- cron: '0 1 * * *' # 每天 UTC 1:00(北京时间 9:00)
workflow_dispatch: # 支持手动触发
jobs:
crawl:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.10'
- run: |
pip install -r requirements.txt
python crawl_notta.py
- uses: actions/upload-artifact@v3
with:
name: crawl-results
path: data/*.csv方式三:本地计划任务(Windows)
使用「任务计划程序」创建定时任务。
5.3 对接 LLM 做内容摘要(进阶)
抓取完数据后,可以用 AI 做二次加工:
import openai
# 为每篇文章生成摘要
for article in articles:
summary = openai.ChatCompletion.create(
model="gpt-4o-mini",
messages=[{
"role": "user",
"content": f"请用一句话总结这篇文章:\n{article['title']}\n{article['excerpt']}"
}]
)
article['ai_summary'] = summary['choices'][0]['message']['content']✅ 质量检查
功能完整性
- 能抓取所有目标字段
- 支持分页/无限滚动
- 增量抓取,不重复处理
稳定性
- 有请求间隔限制(至少 2-3 秒)
- 遇到错误会重试(3 次为宜)
- 有详细的日志输出
数据质量
- 字段类型正确(日期、数字、文本)
- 没有空值或异常值
- URL 是完整的绝对路径
合规性
- 遵守 robots.txt 规则
- 不爬取敏感/需登录的内容
- 有合理的请求间隔
🔁 进阶练习
练习 1:处理 JS 渲染的页面
有些网站数据是 JavaScript 动态加载的,requests 抓不到。
方案:使用 Selenium 或 Playwright
请把爬虫改为使用 Playwright:
- 等待页面完全加载后再抓取
- 支持滚动加载更多内容
- 截图保存当前页面状态pip install playwright
playwright install chromium练习 2:编写多站点爬虫调度器
管理多个爬虫任务:
# scheduler.py
TASKS = [
{'name': 'Notta Blog', 'script': 'crawl_notta.py', 'cron': '0 9 * * *'},
{'name': 'Airtable', 'script': 'crawl_airtable.py', 'cron': '0 10 * * *'},
]
# 按计划执行每个任务
for task in TASKS:
run_crawler(task['script'])
log_result(task['name'], result)练习 3:结合 5.4 和 5.5 做数据产品
- 爬取行业资讯 → 存入数据库
- 用 5.4 后端服务 提供 API
- 用 5.5 SEO 网站 展示聚合内容
- 形成「数据获取 → 加工 → 展示」的完整链路
💡 常见问题
Q:网站结构改了,爬虫就失效怎么办? A:这是常见问题。解决方法:
- 定期检查爬虫是否正常运行
- 把选择器提取到配置文件,方便修改
- 添加自动化测试,网站结构变化时立即告警
Q:如何判断网站是否允许爬取? A:
- 检查
robots.txt文件 - 查看网站的服务条款
- 只爬取公开信息,不爬登录后的内容
- 如有疑问,联系网站管理员询问
Q:被封了怎么办? A:
- 降低请求频率(5-10 秒间隔)
- 使用代理 IP 池
- 模拟真实浏览器行为(Selenium/Playwright)
- 考虑是否有官方 API 可用
Q:如何抓取需要登录的内容? A:
- 使用 Selenium 模拟登录
- 手动获取 Cookie,在请求中携带
- 注意:确保有权限抓取,避免法律风险
🎯 本节小结
完成这个项目后,你应该掌握了:
✅ 如何分析网页结构和定位元素 ✅ 如何编写 Python 爬虫脚本 ✅ 如何处理分页、限速、容错 ✅ 如何将数据存储到各种系统 ✅ 如何定时自动化执行任务
把爬虫结果用起来! 可以是竞品监控、内容聚合、数据分析等。接下来进入 5.4 后端服务,学习如何搭建可对外提供服务的 API。