专项练习 · 9 分钟阅读

Python 爬虫练习:搭建礼貌的抓取流水线

爬虫是一条流水线,不是一次请求。这些练习把抓取、解析、提取和存储分开,让每个阶段都能在不访问真实网站的情况下测试。

从保存的页面开始

开发时下载一次,把 HTML 保存下来,然后反复解析这个样本。这样调试时不受网络波动影响,也方便测试缺失属性、重复链接等边界情况。

from html.parser import HTMLParser

class Links(HTMLParser):
    def __init__(self):
        super().__init__()
        self.links = []
    def handle_starttag(self, tag, attrs):
        href = dict(attrs).get("href")
        if tag == "a" and href:
            self.links.append(href)

p = Links()
p.feed('<a href="/a">A</a><a href="/a">A</a><a href="/b">B</a>')
print(p.links)

可以反复运行的样本

单独构造请求

把请求构造放在一个函数里。真正发送时设置描述清楚的 User-Agent 和超时。本站的浏览器运行器不会发送网络请求,所以这些示例只到 Request 对象为止。

from urllib.request import Request

request = Request(
    "https://example.com/docs",
    headers={"User-Agent": "LearningBot/1.0"},
)
print(request.full_url)
print(request.get_header("User-agent"))

这个示例不联网

按状态码分支

不要把 404 页面当成目标页面解析。用一个小函数把状态判断集中起来,重试策略也就有了唯一的位置。

def outcome(status):
    if 200 <= status < 300:
        return "parse"
    if 300 <= status < 400:
        return "follow redirect"
    if status == 429:
        return "back off"
    return "stop"

print(outcome(200))
print(outcome(429))

一个小的状态策略

保存紧凑的记录

只提取任务需要的字段,其余内容留在原页面。结构化结果可以用字典列表保存,并按稳定键(例如绝对 URL)去重。写入文件或数据库前,结果应当便于检查。

rows = [
    {"url": "/a", "title": "A"},
    {"url": "/a", "title": "A"},
    {"url": "/b", "title": "B"},
]
unique = list({row["url"]: row for row in rows}.values())
print(unique)

每个 URL 一条记录

抓取前先读规则

robots.txt 只是起点,不是全部协议。阅读站点条款,表明客户端身份,限制请求频率;没有合法依据时不要收集个人数据。站点明确拒绝时就停止。

robots = "User-agent: *\nDisallow: /private\nCrawl-delay: 2"
rules = {}
for line in robots.splitlines():
    if ":" in line:
        key, value = line.split(":", 1)
        rules[key.strip().lower()] = value.strip()
print(rules["disallow"])
print(rules["crawl-delay"])

最小但必要的检查

你的练习清单

常见问题

浏览器运行器能抓真实网站吗?

不能。课程运行器用于本地 Python 示例,不会发送任意网络请求。真实抓取应在受控的 Python 环境运行。

应该用 requests 还是 urllib?

两者都可以。urllib 属于标准库;requests 是常用的第三方封装。解析和合规规则相同。

网站阻止我时怎么办?

停止。不要绕过登录、验证码、付费墙或访问控制。应寻找 API 或申请许可。

练习爬虫流水线

12 道题,覆盖请求、HTML 解析、去重和礼貌抓取限制。

打开练习

继续阅读: