Python 初级爬虫教程:Requests 与 Beautiful Soup

Chen Xi
Chen Xi

本教程演示如何抓取一个允许自动访问的静态 HTML 页面,并提取标题和链接。开始前应确认网站服务条款、robots.txt、版权和隐私要求;能访问页面不代表可以任意复制、绕过限制或处理个人信息。

示例于 2026-07-29 按 Requests 与 Beautiful Soup 当前文档复核。请把示例 URL 替换成你有权测试的站点。

1. 安装依赖

1
python -m pip install requests beautifulsoup4

2. 获取网页

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import requests

url = "https://example.com/"
headers = {
"User-Agent": "ExampleResearchBot/1.0 (+https://example.com/bot)"
}

try:
response = requests.get(
url,
headers=headers,
timeout=(5, 15),
)
response.raise_for_status()
except requests.RequestException as error:
raise SystemExit(f"Request failed: {error}") from error

print(response.status_code)

连接和读取都应设置超时,否则程序可能无限等待。raise_for_status() 会把 4xx、5xx 响应转为异常。自定义 User-Agent 应诚实标识用途和联系方式,不应伪装浏览器来绕过访问控制。

3. 解析 HTML

1
2
3
4
5
6
7
8
9
10
11
12
from urllib.parse import urljoin
from bs4 import BeautifulSoup

soup = BeautifulSoup(response.text, "html.parser")

title = soup.title.get_text(strip=True) if soup.title else "(no title)"
print(title)

for anchor in soup.select("a[href]"):
text = anchor.get_text(" ", strip=True)
absolute_url = urljoin(response.url, anchor["href"])
print(text, absolute_url)

CSS 选择器应针对页面稳定结构。真实网页可能缺少字段或改变布局,所以访问属性前要检查,并为解析逻辑编写小规模测试。

4. 保存结构化结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import csv

rows = []
for anchor in soup.select("a[href]"):
rows.append(
{
"text": anchor.get_text(" ", strip=True),
"url": urljoin(response.url, anchor["href"]),
}
)

with open("links.csv", "w", newline="", encoding="utf-8-sig") as file:
writer = csv.DictWriter(file, fieldnames=["text", "url"])
writer.writeheader()
writer.writerows(rows)

把采集时间、来源 URL 和解析版本一并记录,会更利于审计和重跑。

5. 负责任地抓取

  • 先阅读站点政策及 robots.txt,只访问允许的路径。
  • 控制频率,遇到 429Retry-After 时停止或退避。
  • 缓存已获取的页面,避免重复请求。
  • 不绕过登录、验证码、付费墙或其他访问控制。
  • 最小化收集和保存个人数据,设置保留期限。

robots.txt 是站点向自动客户端表达抓取规则的标准机制,但它不是授权书,也不能替代适用法律和服务条款。

需要处理 JavaScript 页面或受控并发时,可继续阅读 Python 进阶爬虫教程

参考资料