第 13 课 | 基础爬虫:requests + BeautifulSoup 爬取 IT之家

竞品监控 Agent 的第一道工序——数据采集。这节课用 requests + BeautifulSoup 搭建第一个爬虫,自动抓取 IT 之家科技新闻,效率提升 10 倍。


一、业务价值:为什么需要爬虫

1.1 一个真实的场景

假设你是某科技公司的市场分析师,每天的工作是:

  1. 打开 IT 之家、36氪、虎嗅等 5-8 个科技媒体
  2. 浏览首页,寻找和公司产品相关的新闻
  3. 复制标题、摘要、发布时间到 Excel
  4. 分类整理,发给团队

这个过程每天至少花 2-3 小时,而且容易遗漏。如果覆盖 10 个数据源,一个人全天都做不完。

1.2 自动化后的效率对比

指标人工方式爬虫自动化提升
单站采集时间20-30 分钟10-30 秒100x
10 站采集时间3-5 小时2-5 分钟60x
遗漏率15-30%0%(全量)-
数据格式手动整理,格式不一结构化存储,统一格式-
可扩展性加一个站多 30 分钟加一个站多 10 行代码-

核心价值:把人从重复劳动中解放出来,把时间花在分析和决策上。

1.3 爬虫在 Agent 系统中的位置

互联网
IT之家/虎嗅/36氪

爬虫模块
自动采集

数据清洗
去重/格式化

嵌入向量
BGE 模型

向量数据库
ChromaDB

AI Agent
检索+分析

爬虫是整个 Agent 系统的数据入口。没有高质量的数据,后面的嵌入、检索、分析都是空中楼阁。


二、爬虫基础原理

2.1 HTTP 请求-响应模型

爬虫的本质是模拟浏览器发送 HTTP 请求,解析服务器返回的 HTML。

目标网站服务器 Python 爬虫 目标网站服务器 Python 爬虫 GET / HTTP/1.1 User-Agent: Mozilla/5.0 HTTP 200 OK ​ BeautifulSoup 解析 HTML 提取标题、摘要、时间 存入 SQLite

2.2 HTML 结构速览

HTML 是树形结构,每个 <div>、<a>、<span> 都是一个节点:

<div class="news-list">
    <div class="news-item">
        <a class="title" href="/article/123">新闻标题</a>
        <span class="summary">新闻摘要...</span>
        <span class="time">2026-08-15</span>
    </div>
</div>

爬虫的工作就是:找到目标节点 → 提取文本或属性。

2.3 三个核心工具

工具作用类比
requests发送 HTTP 请求,获取网页 HTML浏览器地址栏输入 URL
BeautifulSoup解析 HTML,提取指定内容用 CSS 选择器定位元素
SQLite轻量数据库,存储结构化数据Excel 表格,但支持 SQL 查询

三、环境准备

3.1 安装依赖

uv pip install requests beautifulsoup4 lxml
  • requests:HTTP 请求库
  • beautifulsoup4:HTML 解析库
  • lxml:高性能解析器(BeautifulSoup 的底层引擎)

3.2 目标网站分析

我们选择 IT 之家(ithome.com)作为目标,原因:

  1. 科技新闻聚合,内容质量高,适合竞品监控
  2. HTML 结构规整,适合新手练习
  3. 反爬策略相对宽松(相比知乎、豆瓣)

在开始写代码之前,先在浏览器中打开 IT 之家,按 F12 打开开发者工具,观察新闻列表的 HTML 结构:

  • 新闻列表容器:class="new-list"
  • 每条新闻:class="new" 的 li 元素
  • 标题:class="new" 下的 h2 > a 标签
  • 摘要:class="new" 下的 div.c 或有描述文字的元素

四、实战:爬取 IT 之家新闻

4.1 第一步:发送请求

import requests

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
}
url = "https://www.ithome.com/"
response = requests.get(url, headers=headers, timeout=10)
response.encoding = "utf-8"
print(f"状态码: {response.status_code}")  # 200 表示成功

关键点:

  • User-Agent 伪装成浏览器,否则服务器可能拒绝请求
  • timeout=10 设置超时,防止无限等待
  • encoding="utf-8" 指定编码,防止中文乱码

4.2 第二步:解析 HTML

from bs4 import BeautifulSoup

soup = BeautifulSoup(response.text, "lxml")
news_items = soup.select(".new-list .new")  # CSS 选择器
print(f"找到 {len(news_items)} 条新闻")

select() 使用 CSS 选择器语法,比正则表达式更直观、更可靠。

4.3 第三步:提取数据

for item in news_items[:10]:  # 只取前 10 条
    title_elem = item.select_one("h2 a")
    summary_elem = item.select_one(".c")
    time_elem = item.select_one("time")
    
    title = title_elem.text.strip() if title_elem else ""
    summary = summary_elem.text.strip() if summary_elem else ""
    url = title_elem.get("href") if title_elem else ""
    pub_time = time_elem.get("datetime", "") if time_elem else ""
    
    print(f"标题: {title}")
    print(f"摘要: {summary[:50]}...")
    print(f"时间: {pub_time}")
    print("---")

4.4 第四步:存储到 SQLite

import sqlite3

conn = sqlite3.connect("news.db")
conn.execute("""
    CREATE TABLE IF NOT EXISTS news (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        title TEXT,
        summary TEXT,
        url TEXT UNIQUE,
        source TEXT,
        pub_time TEXT,
        crawled_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    )
""")

for item in news_items[:10]:
    # ... 提取数据 ...
    conn.execute(
        "INSERT OR IGNORE INTO news (title, summary, url, source, pub_time) VALUES (?, ?, ?, ?, ?)",
        (title, summary, url, "IT之家", pub_time)
    )

conn.commit()
conn.close()

INSERT OR IGNORE 确保 url 唯一,不会重复插入同一条新闻。


五、职业道德:做有素质的爬虫

5.1 遵守 robots.txt

# 检查 robots.txt
# https://www.ithome.com/robots.txt
# 如果 Disallow 包含你要爬的路径,就不要爬

5.2 请求频率控制

import time
import random

# 每次请求之间随机延迟 1-3 秒
delay = random.uniform(1, 3)
time.sleep(delay)

为什么需要延迟?

  • 高频请求会被服务器封 IP
  • 给服务器造成负担,影响正常用户访问
  • 做个有素质的爬虫开发者

5.3 请求头轮换

import random

USER_AGENTS = [
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/120.0",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Edge/120.0",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 Safari/17.0",
]

headers = {
    "User-Agent": random.choice(USER_AGENTS),
    "Accept": "text/html,application/xhtml+xml",
    "Accept-Language": "zh-CN,zh;q=0.9",
}

六、完整代码运行

code/ithome_crawler.py 是完整的爬虫脚本,包含以上所有功能。

cd code/lesson-13-web-crawler
uv run ithome_crawler.py

运行后生成 data/ithome_news.db,包含爬取的新闻数据:

# 查看数据
sqlite3 data/ithome_news.db "SELECT title, pub_time FROM news LIMIT 5"

运行结果示例

[2026-08-15 14:30:01] 开始爬取 IT之家...
[2026-08-15 14:30:02] 状态码: 200
[2026-08-15 14:30:03] 找到 35 条新闻
[2026-08-15 14:30:03] 已保存: 苹果发布iOS 19开发者预览版
[2026-08-15 14:30:03] 已保存: 华为Mate 80系列曝光
[2026-08-15 14:30:03] 已保存: 特斯拉Optimus机器人量产计划
...
[2026-08-15 14:30:03] 完成!共爬取 35 条新闻,新增 12 条,跳过 23 条(重复)

七、常见问题排查

7.1 状态码不是 200

状态码含义解决方案
403禁止访问加强 User-Agent 伪装,降低请求频率
404页面不存在检查 URL 是否正确
429请求过多增加延迟时间,等待恢复
500服务器错误稍后重试

7.2 解析不到数据

常见原因:

  1. HTML 结构变了:网站改版,CSS 选择器失效 → 重新分析页面结构
  2. 动态加载:内容由 JavaScript 渲染 → 需要 Selenium/Playwright(第 14 课)
  3. 反爬机制:服务器返回了假数据或验证码 → 需要更高级的伪装策略

7.3 中文乱码

response.encoding = response.apparent_encoding  # 自动检测编码
# 或手动指定
response.encoding = "utf-8"

八、总结

这节课我们完成了 Agent 系统的数据入口——爬虫模块:

  1. 业务价值:自动化采集替代人工浏览,效率提升 60-100 倍
  2. 核心技术:requests 发送请求 → BeautifulSoup 解析 HTML → SQLite 存储
  3. 职业道德:遵守 robots.txt、控制请求频率、伪装请求头

下一课,我们将进阶到更复杂的爬虫场景:分析 API 接口直接获取 JSON 数据,以及用 Selenium 处理动态页面。


本课代码:code/lesson-13-web-crawler/ithome_crawler.py

本课数据:code/lesson-13-web-crawler/data/ithome_news.db(运行后生成)

Logo

聚焦RDK与具身智能,汇集机器人开发教程、开源案例和技术交流

更多推荐