㊗️本期内容已收录至专栏《Python爬虫实战》,持续完善知识体系与项目实战,建议先订阅收藏,后续查阅更方便~
㊙️本期爬虫难度指数:⭐⭐⭐
🉐福利: 一次订阅后,专栏内的所有文章可永久免费看,持续更新中,保底1000+(篇)硬核实战内容。

全文目录:
-
- [🌟 开篇语](#🌟 开篇语)
- [🌟 开篇语](#🌟 开篇语)
-
- [1️⃣ 摘要(Abstract)](#1️⃣ 摘要(Abstract))
- [2️⃣ 背景与需求(Why)](#2️⃣ 背景与需求(Why))
- [3️⃣ 合规与注意事项(必写)](#3️⃣ 合规与注意事项(必写))
- [4️⃣ 技术选型与整体流程(What/How)](#4️⃣ 技术选型与整体流程(What/How))
- [5️⃣ 环境准备与依赖安装(可复现)](#5️⃣ 环境准备与依赖安装(可复现))
- [6️⃣ 核心实现:请求层(Fetcher)](#6️⃣ 核心实现:请求层(Fetcher))
- [7️⃣ 核心实现:解析层(Parser)](#7️⃣ 核心实现:解析层(Parser))
- [8️⃣ 数据存储与导出(Storage)](#8️⃣ 数据存储与导出(Storage))
- [9️⃣ 运行方式与结果展示(必写)](#9️⃣ 运行方式与结果展示(必写))
- [🔟 常见问题与排错(强烈建议写)](#🔟 常见问题与排错(强烈建议写))
- [1️⃣1️⃣ 进阶优化(可选但加分)](#1️⃣1️⃣ 进阶优化(可选但加分))
- [1️⃣2️⃣ 总结与延伸阅读](#1️⃣2️⃣ 总结与延伸阅读)
- [🌟 文末](#🌟 文末)
-
- [✅ 专栏持续更新中|建议收藏 + 订阅](#✅ 专栏持续更新中|建议收藏 + 订阅)
- [✅ 互动征集](#✅ 互动征集)
- [✅ 免责声明](#✅ 免责声明)
🌟 开篇语
哈喽,各位小伙伴们你们好呀~我是【喵手】。
运营社区: C站 / 掘金 / 腾讯云 / 阿里云 / 华为云 / 51CTO
欢迎大家常来逛逛,一起学习,一起进步~🌟
我长期专注 Python 爬虫工程化实战 ,主理专栏 《Python爬虫实战》:从采集策略 到反爬对抗 ,从数据清洗 到分布式调度 ,持续输出可复用的方法论与可落地案例。内容主打一个"能跑、能用、能扩展 ",让数据价值真正做到------抓得到、洗得净、用得上。
📌 专栏食用指南(建议收藏)
- ✅ 入门基础:环境搭建 / 请求与解析 / 数据落库
- ✅ 进阶提升:登录鉴权 / 动态渲染 / 反爬对抗
- ✅ 工程实战:异步并发 / 分布式调度 / 监控与容错
- ✅ 项目落地:数据治理 / 可视化分析 / 场景化应用
📣 专栏推广时间 :如果你想系统学爬虫,而不是碎片化东拼西凑,欢迎订阅专栏👉《Python爬虫实战》👈,一次订阅后,专栏内的所有文章可永久免费阅读,持续更新中。
💕订阅后更新会优先推送,按目录学习更高效💯~
🌟 开篇语
哈喽,各位小伙伴们你们好呀~我是【喵手】。
运营社区: C站 / 掘金 / 腾讯云 / 阿里云 / 华为云 / 51CTO
欢迎大家常来逛逛,一起学习,一起进步~🌟
我长期专注 Python 爬虫工程化实战 ,主理专栏 《Python爬虫实战》:从采集策略 到反爬对抗 ,从数据清洗 到分布式调度 ,持续输出可复用的方法论与可落地案例。内容主打一个"能跑、能用、能扩展 ",让数据价值真正做到------抓得到、洗得净、用得上。
📌 专栏食用指南(建议收藏)
- ✅ 入门基础:环境搭建 / 请求与解析 / 数据落库
- ✅ 进阶提升:登录鉴权 / 动态渲染 / 反爬对抗
- ✅ 工程实战:异步并发 / 分布式调度 / 监控与容错
- ✅ 项目落地:数据治理 / 可视化分析 / 场景化应用
📣 专栏推广时间 :如果你想系统学爬虫,而不是碎片化东拼西凑,欢迎订阅/关注专栏👉《Python爬虫实战》👈
💕订阅后更新会优先推送,按目录学习更高效💯~
1️⃣ 摘要(Abstract)
一句话概述: 本项目使用 Python 的 requests 和 BeautifulSoup 库,针对图书沙盒网站构建高效爬虫,将书籍的标题、价格、评分及库存状态结构化提取并持久化存储。
读完本文你将获得:
- 🎯 掌握从 HTTP 请求到数据清洗(ETL)的完整爬虫链路。
- 🛠️ 学会使用 CSS 选择器精准提取复杂的 HTML 字段。
- 📦 拥有一份可直接运行、具备基本容错能力的工程级代码模板。
2️⃣ 背景与需求(Why)
在信息爆炸时代,数据即资产。作为一名数据爱好者,手动复制粘贴不仅低效,更无法进行规模化分析。我们需要自动化手段来获取竞争对手的定价数据或行业趋势。
本次行动目标:
-
目标站点:
http://books.toscrape.com/(一个安全的练习靶场) -
核心需求: 遍历图书列表,抓取详情。
-
目标字段清单:
title(书名 - 文本)price(价格 - 浮点数)rating(评分 - 转换后的数字 1-5)availability(库存状态 - 布尔值或文本)detail_url(详情页链接 - URL)
3️⃣ 合规与注意事项(必写)
做爬虫,**"讲武德"**是第一条军规。🛡️
- Robots 协议: 在开工前,先查看
robots.txt。虽然靶场网站允许抓取,但在真实实战中,必须尊重User-agent: * Disallow: /的声明。 - 频率控制(Rate Limiting): 这一条至关重要!切勿使用攻击式的并发请求(如 100 线程/秒),这会导致对方服务器宕机(DoS),甚至招致 IP 封禁。我们会设置合理的
time.sleep。 - 数据伦理: 本项目仅抓取公开数据,绝不触碰用户隐私(PII),也不涉及绕过付费墙或破解登录验证。做一名合法的"数据采集者",而不是"黑客"。
4️⃣ 技术选型与整体流程(What/How)
选型分析:
目标网站是典型的静态 HTML 网站(服务端渲染)。页面源代码中包含了我们所需的所有数据,不需要执行 JavaScript。
- 方案:
Python+Requests(发送请求) +BeautifulSoup4(解析 HTML)。 - 为什么不用 Scrapy? 对于单页面结构简单、量级较小(<1000页)的任务,Scrapy 显得过于重型,配置繁琐。
- 为什么不用 Selenium/Playwright? 既然是静态页面,用浏览器自动化工具会极大降低抓取速度,属于"杀鸡用牛刀"。
- Fetcher(采集): 伪装浏览器发送 GET 请求。
- Parser(解析): 定位 DOM 节点,提取脏数据。
- Cleaner(清洗): 去除货币符号,将 "Three" 转为数字 3。
- Storage(存储): 写入 CSV 文件。
5️⃣ 环境准备与依赖安装(可复现)
确保你的 Python 版本 >= 3.8(人生苦短,请用新版本)。
项目目录结构推荐:
text
project_root/
│
├── data/ # 存放抓取结果
├── src/ # 源代码目录
│ └── main.py # 入口文件
├── requirements.txt # 依赖清单
└── README.md
依赖安装:
打开终端(Terminal),执行以下命令来武装你的环境:
bash
pip install requests beautifulsoup4 pandas
6️⃣ 核心实现:请求层(Fetcher)
在网络的世界里,我们需要给自己穿上一层"伪装衣"。
python
import requests
from requests.exceptions import RequestException
import time
import random
def fetch_page(url):
"""
通用请求函数,包含基本的反爬伪装和错误处理
"""
# 伪装成正常的 Chrome 浏览器
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
'Referer': 'http://books.toscrape.com/'
}
try:
# timeout 是必须的!防止网络卡死导致程序无限挂起
response = requests.get(url, headers=headers, timeout=10)
# 检查 HTTP 状态码,如果是 4xx 或 5xx 直接抛出异常
response.raise_for_status()
# 显式设置编码,防止中文乱码(虽然这里是英文站,但养成好习惯)
response.encoding = response.apparent_encoding
return response.text
except RequestException as e:
print(f"💥 请求失败: {url} | 错误信息: {e}")
return None
# 简单的随机延时,模拟人类阅读间隔
finally:
time.sleep(random.uniform(0.5, 1.5))
7️⃣ 核心实现:解析层(Parser)
这是爬虫的大脑。我们需要从杂乱的 HTML 中"手术刀"般地切出我们需要的数据。这里我们使用 CSS Selector,它比 XPath 写起来更简洁。
python
from bs4 import BeautifulSoup
def parse_html(html_content):
"""
解析 HTML 并提取书籍列表信息
"""
if not html_content:
return []
soup = BeautifulSoup(html_content, 'html.parser')
books_data = []
# 找到所有的书籍卡片容器
articles = soup.select('article.product_pod')
for article in articles:
try:
# 1. 提取标题 (Title)
title_tag = article.select_one('h3 > a')
title = title_tag['title'] if title_tag else "Unknown Title"
# 2. 提取价格 (Price)
price_text = article.select_one('p.price_color').text
# 清洗数据:去掉英镑符号 '£'
price = float(price_text.replace('£', ''))
# 3. 提取评分 (Rating)
# class 属性通常是列表,如 ['star-rating', 'Three']
star_class = article.select_one('p.star_rating')['class']
rating_map = {'One': 1, 'Two': 2, 'Three': 3, 'Four': 4, 'Five': 5}
# 找到对应的数字文本
rating_text = [x for x in star_class if x in rating_map]
rating = rating_map.get(rating_text[0], 0) if rating_text else 0
# 4. 提取状态 (Availability)
avail_text = article.select_one('p.instock.availability').text.strip()
is_in_stock = True if 'In stock' in avail_text else False
data = {
'title': title,
'price': price,
'rating': rating,
'in_stock': is_in_stock
}
books_data.append(data)
except AttributeError as e:
# 容错处理:某个字段缺失不应导致整个程序崩溃
print(f"⚠️ 解析单条数据出错: {e}")
continue
return books_data
8️⃣ 数据存储与导出(Storage)
既然是做数据分析,CSV 是最通用的格式。为了方便,我们直接使用神器 Pandas。
python
import pandas as pd
import os
def save_to_csv(data_list, filename="books_data.csv"):
"""
将字典列表保存为 CSV 文件
"""
if not data_list:
print("📭 没有数据需要保存。")
return
# 转换为 DataFrame
df = pd.DataFrame(data_list)
# 确保目录存在
os.makedirs('data', exist_ok=True)
filepath = os.path.join('data', filename)
# 导出
df.to_csv(filepath, index=False, encoding='utf-8-sig')
print(f"💾 数据已成功保存至: {filepath} | 共 {len(df)} 条记录")
9️⃣ 运行方式与结果展示(必写)
这是我们将所有积木拼在一起的时刻!🧩
主程序入口 (main.py):
python
# 将上面的 fetch_page, parse_html, save_to_csv 整合
def main():
base_url = "http://books.toscrape.com/catalogue/page-{}.html"
all_books = []
print("🚀 爬虫启动...")
# 演示抓取前 3 页
for page in range(1, 4):
print(f"📡 正在抓取第 {page} 页...")
url = base_url.format(page)
html = fetch_page(url)
if html:
books = parse_html(html)
all_books.extend(books)
print(f" ✅ 第 {page} 页解析完成,获取 {len(books)} 本书。")
# 存储结果
save_to_csv(all_books, filename="scraped_books_v1.csv")
# 展示前 3 条结果
print("\n📊 结果预览:")
for book in all_books[:3]:
print(book)
if __name__ == "__main__":
main()
控制台输出示例:
text
🚀 爬虫启动...
📡 正在抓取第 1 页...
✅ 第 1 页解析完成,获取 20 本书。
...
💾 数据已成功保存至: data/scraped_books_v1.csv | 共 60 条记录
📊 结果预览:
{'title': 'A Light in the Attic', 'price': 51.77, 'rating': 3, 'in_stock': True}
{'title': 'Tipping the Velvet', 'price': 53.74, 'rating': 1, 'in_stock': True}
{'title': 'Soumission', 'price': 50.1, 'rating': 1, 'in_stock': True}
🔟 常见问题与排错(强烈建议写)
老司机翻车现场指南:
-
40Forbidden / 429 Too Many Requests:
- 原因: 没加 User-Agent 头(裸奔),或者爬太快了。
- 解法: 检查
headers 是否完整;增大time.sleep()` 的时间;如果是 IP 封禁,需要上代理池(Proxy Pool)。
-
HTML 抓取到空壳(Body 里没数据):
- *原因 网站是 Vue/React 动态渲染的,数据在 JS 里。
- *解法 打开浏览器开发者工具(F12)-> Network -> XHR/Fetch,找真实的 API 接口。如果 API 加密严重,改用 Selenium/Playwright。
-
解析报错
AttributeError: 'eType' object has no attribute 'text':- 原因: CSS 选择器失效了,或者由于广告/缺货导致页面结构变了。
- 解法: 必须加
try-except或if tag:判断(参考代码第 7 节的容错处理)。
1️⃣1️⃣ 进阶优化(可选但加分)
如果你想让你的爬虫更"专业":
- 多线程并发: 使用
concurrent.futures.ThreadPoolExecutor。对于 I/O 密集型任务(网络请求),可以将速度提升 5-10 倍。 - 断点续跑: 在数据库或 Redis 中记录已经抓取过的 URL Hash。程序重启时,跳过已抓取的页面。
- 日志系统: 别再用
print调试了!引入 Python 的logging模块,将报错信息写入scraper.log文件。
1️⃣2️⃣ 总结与延伸阅读
复
今天我们成功构建了一个针对静态网站的 ETL 爬虫。虽然简单,但它涵盖了爬虫最核心的四步:请求、解析、清洗、入库。你现在拥有了一个可以扩展的基础框架。
下一步挑战:
- 试试抓取 JavaScript 动态渲染 的网站(如雪球网、SPA 电商)。
- 学习 Scrapy 框架,体验中间件和管道的强大。
- 研究 反爬虫对抗(JS 逆向、验证码识别),那是爬虫领域的深水区。🌊
🌟 文末
好啦~以上就是本期的全部内容啦!如果你在实践过程中遇到任何疑问,欢迎在评论区留言交流,我看到都会尽量回复~咱们下期见!
小伙伴们在批阅的过程中,如果觉得文章不错,欢迎点赞、收藏、关注哦~
三连就是对我写作道路上最好的鼓励与支持! ❤️🔥
✅ 专栏持续更新中|建议收藏 + 订阅
墙裂推荐订阅专栏 👉 《Python爬虫实战》,本专栏秉承着以"入门 → 进阶 → 工程化 → 项目落地"的路线持续更新,争取让每一期内容都做到:
✅ 讲得清楚(原理)|✅ 跑得起来(代码)|✅ 用得上(场景)|✅ 扛得住(工程化)
📣 想系统提升的小伙伴 :强烈建议先订阅专栏 《Python爬虫实战》,再按目录大纲顺序学习,效率十倍上升~

✅ 互动征集
想让我把【某站点/某反爬/某验证码/某分布式方案】等写成某期实战?
评论区留言告诉我你的需求,我会优先安排实现(更新)哒~
⭐️ 若喜欢我,就请关注我叭~(更新不迷路)
⭐️ 若对你有用,就请点赞支持一下叭~(给我一点点动力)
⭐️ 若有疑问,就请评论留言告诉我叭~(我会补坑 & 更新迭代)
✅ 免责声明
本文爬虫思路、相关技术和代码仅用于学习参考,对阅读本文后的进行爬虫行为的用户本作者不承担任何法律责任。
使用或者参考本项目即表示您已阅读并同意以下条款:
- 合法使用: 不得将本项目用于任何违法、违规或侵犯他人权益的行为,包括但不限于网络攻击、诈骗、绕过身份验证、未经授权的数据抓取等。
- 风险自负: 任何因使用本项目而产生的法律责任、技术风险或经济损失,由使用者自行承担,项目作者不承担任何形式的责任。
- 禁止滥用: 不得将本项目用于违法牟利、黑产活动或其他不当商业用途。
- 使用或者参考本项目即视为同意上述条款,即 "谁使用,谁负责" 。如不同意,请立即停止使用并删除本项目。!!!
