Python 现代开发学习笔记

(一)从一条响应扩展到整份目录

1. 把采集任务拆成可以核对的动作

自拟任务:采集阅读目录。 练习站提供三页目录,每页三张卡片;每张卡片给出源站编号、书名和详情链接。详情页才提供完整的阅读状态与标签。采集器输出去重后的六本书,保留来源信息,再导出前面书籍库已经能读取的 CSV 和 SQLite 数据。

目录页 卡片中的源站编号 本页新发现的书
第 1 页 b101、b102、b101 b101、b102
第 2 页 b102、b103、b104 b103、b104
第 3 页 b104、b105、b106 b105、b106

手算得到 3 + 3 + 3 = 9 张卡片,其中 b101、b102、b104 各有一次重复,最终是六本。两本已经读完,四本未读。程序除了核对数量,还要核对具体编号、字段与请求记录:只输出一个 6,并不能说明采集内容完整。

从九张目录卡片发现链接,再取六个详情、校验记录与保存进度的完整数据流

2. 在项目环境中准备解析工具

进入配套 crawler_project。crawlsite 是本机练习站,catalogcrawl 是本章逐步构建的采集器,bookdata 继续复用第五章的数据层。

# 项目文件:crawler_project/pyproject.toml
# 基本采集用 HTTPX 和 Beautiful Soup;浏览器与 Scrapy 按后面的练习分别安装。
[build-system]
requires = ["setuptools>=80,<83"]
build-backend = "setuptools.build_meta"

[project]
name = "reading-crawler-notes"
version = "0.1.0"
requires-python = ">=3.12,<3.13"
dependencies = ["httpx>=0.28,<1", "beautifulsoup4>=4.14,<5"]

[project.optional-dependencies]
browser = ["playwright>=1.55,<2"]
scrapy = ["scrapy>=2.13,<3"]

[project.scripts]
crawl-books = "catalogcrawl.cli:main"

[dependency-groups]
dev = ["pytest>=9.1,<10"]

[tool.setuptools.packages.find]
where = ["src"]

[tool.pytest.ini_options]
testpaths = ["tests"]
addopts = "-ra --import-mode=importlib"

这里的分发名是 beautifulsoup4,代码中从 bs4 导入 BeautifulSoup。浏览器和 Scrapy 放在可选依赖中,读到对应小节时再安装;pytest 仍属于开发组。

# 在 crawler_project 中按锁定记录准备 Python 3.12 项目环境。
uv sync --locked
# 手动查看练习站:浏览器访问显示的地址,Ctrl+C 结束。
uv run python -m crawlsite --port 8766

短例用 with running_site() as site 临时启动相同站点,由系统分配空闲端口,退出后关闭。它们在本目录按 uv run python ../demos/client_sync.py 这样的方式运行。pip 路线先在 Python 3.12 虚拟环境中执行 python -m pip install -e .,再执行 python -m pip install -r requirements-dev.txt,之后用该环境的解释器启动同样的文件。

笔记正文与全部题解 · Ctrl / ⌘ K