Skip to Content

5.3 做一个爬虫

目标:掌握「分析网页结构 → 写脚本 → 增量抓取 → 数据落地」的流程,让 AI 成为你的数据抓手。

爬虫是数据获取的重要手段,无论是竞品分析、内容聚合还是市场研究,都离不开自动化数据抓取。这个项目将教会你如何分析网页、编写 Python 脚本、处理数据并持久化存储。

🎯 成品要求

  • 针对指定站点抓取所需字段,支持增量更新(不重复抓取)
  • 把结果写入 CSV/数据库/飞书多维表格等外部系统
  • 有日志输出,遇到失败能定位原因
  • 有基本的容错机制(限速、重试)

🧰 准备工作

1. 工具选择

  • Cursor/Trae + Claude Code:支持终端运行 Python
  • Python 环境:本地 Python 3.10+,或使用 Replit/CodeSandbox 提供的在线环境

2. 目标站点选择

练习站点建议(选择结构清晰、无反爬的站点):

注意事项:

  • 检查 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 使用浏览器开发者工具

  1. 右键页面 → 点击「检查」(或按 F12
  2. 点击左上角的「选择元素」图标(或 Ctrl+Shift+C
  3. 鼠标悬停在文章卡片上,查看 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.py

3.2 常见问题排查

症状可能原因排查思路解决方案
403 / 429 错误被识别为爬虫或请求过快检查 User-Agent、请求频率增加 User-Agent 头部;限速改为 5-10 秒;使用代理 IP
数据为空选择器不匹配打印 HTML 源码,检查实际结构用浏览器复制实际的 class/id;检查是否 JS 渲染
日期格式错误不同语言的日期格式打印原始日期字符串使用 dateutil.parser 或正则表达式
编码乱码网页编码不是 UTF-8检查响应头 Content-Typeresponse.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-oapi

5.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:这是常见问题。解决方法:

  1. 定期检查爬虫是否正常运行
  2. 把选择器提取到配置文件,方便修改
  3. 添加自动化测试,网站结构变化时立即告警

Q:如何判断网站是否允许爬取? A:

  1. 检查 robots.txt 文件
  2. 查看网站的服务条款
  3. 只爬取公开信息,不爬登录后的内容
  4. 如有疑问,联系网站管理员询问

Q:被封了怎么办? A:

  1. 降低请求频率(5-10 秒间隔)
  2. 使用代理 IP 池
  3. 模拟真实浏览器行为(Selenium/Playwright)
  4. 考虑是否有官方 API 可用

Q:如何抓取需要登录的内容? A:

  1. 使用 Selenium 模拟登录
  2. 手动获取 Cookie,在请求中携带
  3. 注意:确保有权限抓取,避免法律风险

🎯 本节小结

完成这个项目后,你应该掌握了:

✅ 如何分析网页结构和定位元素 ✅ 如何编写 Python 爬虫脚本 ✅ 如何处理分页、限速、容错 ✅ 如何将数据存储到各种系统 ✅ 如何定时自动化执行任务

把爬虫结果用起来! 可以是竞品监控、内容聚合、数据分析等。接下来进入 5.4 后端服务,学习如何搭建可对外提供服务的 API。

Last updated on