当前位置: 首页 > news >正文

Python爬虫实战:从零构建高可用静态网页抓取管道!

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

全文目录:

      • 🌟 开篇语
      • 0️⃣ 前言(Preface)
      • 1️⃣ 摘要(Abstract)
      • 2️⃣ 背景与需求(Why)
      • 3️⃣ 合规与注意事项(必写)
      • 4️⃣ 技术选型与整体流程(What/How)
      • 5️⃣ 环境准备与依赖安装(可复现)
      • 6️⃣ 核心实现:请求层(Fetcher)
      • 7️⃣ 核心实现:解析层(Parser)
      • 8️⃣ 数据存储与导出(Storage)
      • 9️⃣ 运行方式与结果展示(必写)
      • 🔟 常见问题与排错(强烈建议写)
      • 1️⃣1️⃣ 进阶优化(可选但加分)
      • 1️⃣2️⃣ 总结与延伸阅读
      • 🌟 文末
        • ✅ 专栏持续更新中|建议收藏 + 订阅
        • ✅ 互动征集
        • ✅ 免责声明

🌟 开篇语

哈喽,各位小伙伴们你们好呀~我是【喵手】。
运营社区: C站 / 掘金 / 腾讯云 / 阿里云 / 华为云 / 51CTO
欢迎大家常来逛逛,一起学习,一起进步~🌟

我长期专注Python 爬虫工程化实战,主理专栏 《Python爬虫实战》:从采集策略反爬对抗,从数据清洗分布式调度,持续输出可复用的方法论与可落地案例。内容主打一个“能跑、能用、能扩展”,让数据价值真正做到——抓得到、洗得净、用得上

📌专栏食用指南(建议收藏)

  • ✅ 入门基础:环境搭建 / 请求与解析 / 数据落库
  • ✅ 进阶提升:登录鉴权 / 动态渲染 / 反爬对抗
  • ✅ 工程实战:异步并发 / 分布式调度 / 监控与容错
  • ✅ 项目落地:数据治理 / 可视化分析 / 场景化应用

📣专栏推广时间:如果你想系统学爬虫,而不是碎片化东拼西凑,欢迎订阅专栏👉《Python爬虫实战》👈,一次订阅后,专栏内的所有文章可永久免费阅读,持续更新中。

💕订阅后更新会优先推送,按目录学习更高效💯~

0️⃣ 前言(Preface)

兄弟们,今天咱们不搞虚的。这篇文章只做一件事:带你用requests+BeautifulSoup从头到尾撸一个健壮的静态网页爬虫,最终把名言佳句连带作者和标签打包塞进本地 CSV 文件里。

读完这篇你将获得:

  1. 掌握一套可以直接复用于 80% 静态网页的爬虫模板代码。
  2. 学会如何优雅地处理请求重试、异常捕捉和反爬伪装。
  3. 搞懂数据解析与存储的工程化标准姿势。

1️⃣ 摘要(Abstract)

本文以抓取 quotes.toscrape.com 名言数据为例,详细演示了基于 Python 的轻量级爬虫开发全链路。采用requests进行网络请求,BeautifulSoup解析 HTML DOM 树,最终输出结构化 CSV 文件。
读完能获得什么:

  1. 从 0 到 1 的 Python 爬虫工程化思维。
  2. 应对常见网络波动与解析容错的实战技巧。
  3. 一份可以直接拿来二次开发的源码。

2️⃣ 背景与需求(Why)

为什么要写这个爬虫?说实话,日常工作中我们经常需要聚合垂直领域的信息(比如行业新闻、竞品动态、或者是为了训练 NLP 模型收集语料)。手动复制粘贴?太傻了,那是上个世纪的玩法。我们需要自动化!
本次目标站点为沙盒测试网:http://quotes.toscrape.com/
目标字段清单:

  • Quote_Text(名言内容) - 字符串
  • Author(作者姓名) - 字符串
  • Tags(关联标签) - 列表/逗号分隔字符串

3️⃣ 合规与注意事项(必写)

在开始敲代码之前,有些底线咱们必须得聊清楚,这关乎到你能不能安心睡觉。

  • 关于 robots.txt:每次动手前,先去网站根目录看看robots.txt。虽然咱们这次爬的是沙盒网站(随意爬),但在实战中,尊重君子协议是职业素养。
  • 频率控制:做人留一线。千万别用while True毫无节制地发并发请求去打别人的服务器。我们在代码里会加入time.sleep(),模拟人类正常的浏览速度。
  • 底线原则:绝对不碰后台敏感数据,不尝试绕过强制登录和付费墙,采集公开的、不涉及个人隐私的展示型数据。我们只是互联网公开信息的搬运工。

4️⃣ 技术选型与整体流程(What/How)

这次的目标是一个标准的静态网页。服务端直接把数据渲染在 HTML 里返回了,不用我们去扣复杂的 JS 逆向或者抓 XHR 接口。
流程闭环:采集请求 → DOM 解析 → 脏数据清洗 → 结构化存储

  • 为什么选 requests + bs4?

    • 因为轻!杀鸡焉用牛刀,爬个几百页的静态站上 Scrapy 有点大炮打蚊子,用 Playwright 又显得太笨重(无头浏览器太吃内存)。requests负责稳准狠地把源码拉下来,bs4负责优雅地剥离标签,足够了。

5️⃣ 环境准备与依赖安装(可复现)

废话不多说,先把环境搞定。

  • Python 版本:推荐 Python 3.8+(我本地是 3.10,稳如老狗)

  • 依赖安装:打开你的终端,一把梭:

    pipinstallrequests beautifulsoup4 pandas
  • 项目结构推荐

    quote_spider/ ├── main.py # 主入口文件 ├── fetcher.py # 请求层 ├── parser.py # 解析层 ├── storage.py # 存储层 └── data/ # 存放输出的CSV

    为了方便你直接复制运行,我接下来的代码会整合成一个单文件版本,但在真实业务里,强烈建议按上面的结构拆分解耦!

6️⃣ 核心实现:请求层(Fetcher)

网络请求绝对不是requests.get(url)这么简单。老手都知道,网络环境是极其不可靠的。
这部分必须加入:随机 User-Agent(伪装成不同浏览器)、超时控制(防假死)、以及重试机制。

importrequestsimporttimeimportrandomfromrequests.exceptionsimportRequestException# 准备几个常见的UAUSER_AGENTS=["Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36","Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36"]deffetch_page(url,retries=3):""" 负责安全的获取网页源码,包含重试和伪装 """headers={'User-Agent':random.choice(USER_AGENTS),'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8','Referer':'http://quotes.toscrape.com/'# 告诉服务器我从哪里来}foriinrange(retries):try:# timeout设置:连接3秒,读取7秒response=requests.get(url,headers=headers,timeout=(3,7))response.raise_for_status()# 如果状态码不是200,直接抛异常response.encoding='utf-8'# 强制编码,防止乱码returnresponse.textexceptRequestExceptionase:print(f"[-] 请求失败 ({url}):{e}. 正在进行第{i+1}次重试...")time.sleep(2)# 遇到错误缓一缓再上print(f"[x] 彻底放弃请求:{url}")returnNone

7️⃣ 核心实现:解析层(Parser)

拿到 HTML 后,用 BeautifulSoup 的 CSS 选择器提取内容。
容错极其重要:有时候某个名言可能没有标签(Tags),如果不加try-except或默认值判断,程序当场就会崩掉。

frombs4importBeautifulSoupdefparse_html(html_content):""" 解析HTML,提取核心字段,处理缺失值 """ifnothtml_content:return[]soup=BeautifulSoup(html_content,'html.parser')quotes_data=[]# CSS选择器:找到所有包含名言的div大盒子quote_blocks=soup.select('div.quote')forblockinquote_blocks:# 提取名言文本text_element=block.select_one('span.text')quote_text=text_element.get_text(strip=True)iftext_elementelse"未知内容"# 提取作者author_element=block.select_one('small.author')author=author_element.get_text(strip=True)ifauthor_elementelse"佚名"# 提取标签 (有些可能没有标签,需要容错)tags_elements=block.select('div.tags a.tag')tags=[tag.get_text(strip=True)fortagintags_elements]iftags_elementselse[]quotes_data.append({'Quote_Text':quote_text,'Author':author,'Tags':",".join(tags)# 将列表转为逗号分隔的字符串存入CSV更方便})returnquotes_data

8️⃣ 数据存储与导出(Storage)

数据爬下来放内存里那是闹着玩,必须落盘。为了简单直观,我们选用 CSV 格式。利用 Pandas 可以优雅地处理字典列表并一键导出。

字段映射表:

字段名 (Field)类型 (Type)示例值 (Example)
Quote_TextString“The world as we have created it…”
AuthorStringAlbert Einstein
TagsStringchange,deep-thoughts,thinking
importpandasaspdimportosdefsave_to_csv(data_list,filename='quotes_output.csv'):""" 持久化存储到本地,支持追加模式或覆盖模式 """ifnotdata_list:print("[-] 没有数据可保存!")returndf=pd.DataFrame(data_list)# 简单的去重策略:利用 pandas 根据名言内容去重df.drop_duplicates(subset=['Quote_Text'],keep='first',inplace=True)# 检查文件是否存在,决定是否写入表头file_exists=os.path.isfile(filename)df.to_csv(filename,mode='a',index=False,encoding='utf-8-sig',header=notfile_exists)print(f"[+] 成功保存{len(df)}条数据到{filename}")

9️⃣ 运行方式与结果展示(必写)

万事俱备,拼装主逻辑!我们要处理翻页逻辑(从第 1 页爬到第 3 页作为演示)。

defmain():base_url="http://quotes.toscrape.com/page/{}/"total_pages_to_scrape=3all_extracted_data=[]print("[*] 爬虫启动!开始采蜜... 🐝")forpageinrange(1,total_pages_to_scrape+1):target_url=base_url.format(page)print(f"[*] 正在抓取第{page}页:{target_url}")html=fetch_page(target_url)page_data=parse_html(html)ifpage_data:all_extracted_data.extend(page_data)# 频率控制:每爬完一页歇一会儿,文明爬虫从我做起time.sleep(random.uniform(1.5,3.0))# 存储并展示save_to_csv(all_extracted_data)# 打印前 3 行验验货print("\n[+] 最终结果采样展示 (Top 3):")forrowinall_extracted_data[:3]:print(f"作者:{row['Author']}| 名言:{row['Quote_Text'][:30]}... | 标签:{row['Tags']}")if__name__=="__main__":main()

如何启动:
把上述所有代码块按顺序贴到一个名为scraper.py的文件里,然后在命令行执行:
python scraper.py

运行输出展示:

[*] 爬虫启动!开始采蜜... 🐝 [*] 正在抓取第 1 页: http://quotes.toscrape.com/page/1/ [*] 正在抓取第 2 页: http://quotes.toscrape.com/page/2/ [*] 正在抓取第 3 页: http://quotes.toscrape.com/page/3/ [+] 成功保存 30 条数据到 quotes_output.csv [+] 最终结果采样展示 (Top 3): 作者: Albert Einstein | 名言: “The world as we have created it... | 标签: change,deep-thoughts,thinking,world 作者: J.K. Rowling | 名言: “It is our choices, Harry, tha... | 标签: abilities,choices 作者: Albert Einstein | 名言: “There are only two ways to li... | 标签: inspirational,life,live,miracle,miracles

🔟 常见问题与排错(强烈建议写)

爬虫这活儿,80% 的时间在修 Bug 和对抗反爬。

  • 403 Forbidden / 429 Too Many Requests 怎么办?
    说明你被盯上了。检查 headers 里的User-Agent有没有写;加代理池(Proxy Pool);把time.sleep()的时间调大,切忌无脑并发。
  • 右键能看到源码,代码抓下来却抓了个空壳怎么办?
    兄弟,你遇到动态渲染了(Vue/React 写的单页应用)。解决方法有两个:按 F12 去 Network 面板找真正的 XHR/Fetch API 接口直接抓 JSON 数据(上策);或者上Playwright驱动真实浏览器渲染后提取(下策,较慢)。
  • 解析频繁报错(AttributeError: ‘NoneType’ object has no attribute ‘get_text’)
    这是最经典的错误。说明你的 CSS 选择器失效了,或者页面结构不稳定(这页有这标签,那页没有)。必须像我代码里那样加if element else 默认值的容错机制。
  • 编码/乱码如何处理?
    抓取中文网页时常见。在 request 获取响应后,显式声明编码:response.encoding = response.apparent_encoding或者直接指定'utf-8'。导出 CSV 时一定要用'utf-8-sig',否则 Excel 打开绝对是乱码。

1️⃣1️⃣ 进阶优化(可选但加分)

目前这套代码爬个几万页不在话下,但如果数据量来到百万级,这就力不从心了。后续可以往这些方向卷:

  • 并发提速:引入concurrent.futures.ThreadPoolExecutor搞多线程,或者直接重构为asyncio+aiohttp的异步爬虫,速度起飞。
  • 断点续跑:把抓取过的 URL 做一个 MD5 Hash 存入 Redis 的 Set 里面做增量过滤。万一中途断网了,下次启动跳过已爬的链接。
  • 监控与告警:写个简单的拦截器,连续 5 次请求失败直接给你的钉钉/企业微信发个机器人报警。

1️⃣2️⃣ 总结与延伸阅读

复盘一下,今天我们手搓了一个完整的爬虫 Pipeline:解决了 HTTP 请求的伪装、优雅地提取了非结构化的 HTML DOM、处理了容错,并最终输出了干净的 CSV 文件。这不仅是一段代码,这是一种数据获取的工程化思维。

下一步玩什么?
如果你觉得requests写法太原始,强烈建议去学习一下Scrapy框架,那是工业级爬虫的标配。如果是被复杂的 JS 加密折磨得死去活来,可以了解一下Playwright

🌟 文末

好啦~以上就是本期的全部内容啦!如果你在实践过程中遇到任何疑问,欢迎在评论区留言交流,我看到都会尽量回复~咱们下期见!

小伙伴们在批阅的过程中,如果觉得文章不错,欢迎点赞、收藏、关注哦~
三连就是对我写作道路上最好的鼓励与支持!❤️🔥

✅ 专栏持续更新中|建议收藏 + 订阅

墙裂推荐订阅专栏 👉 《Python爬虫实战》,本专栏秉承着以“入门 → 进阶 → 工程化 → 项目落地”的路线持续更新,争取让每一期内容都做到:

✅ 讲得清楚(原理)|✅ 跑得起来(代码)|✅ 用得上(场景)|✅ 扛得住(工程化)

📣想系统提升的小伙伴:强烈建议先订阅专栏 《Python爬虫实战》,再按目录大纲顺序学习,效率十倍上升~

✅ 互动征集

想让我把【某站点/某反爬/某验证码/某分布式方案】等写成某期实战?

评论区留言告诉我你的需求,我会优先安排实现(更新)哒~


⭐️ 若喜欢我,就请关注我叭~(更新不迷路)
⭐️ 若对你有用,就请点赞支持一下叭~(给我一点点动力)
⭐️ 若有疑问,就请评论留言告诉我叭~(我会补坑 & 更新迭代)


✅ 免责声明

本文爬虫思路、相关技术和代码仅用于学习参考,对阅读本文后的进行爬虫行为的用户本作者不承担任何法律责任。

使用或者参考本项目即表示您已阅读并同意以下条款:

  • 合法使用: 不得将本项目用于任何违法、违规或侵犯他人权益的行为,包括但不限于网络攻击、诈骗、绕过身份验证、未经授权的数据抓取等。
  • 风险自负: 任何因使用本项目而产生的法律责任、技术风险或经济损失,由使用者自行承担,项目作者不承担任何形式的责任。
  • 禁止滥用: 不得将本项目用于违法牟利、黑产活动或其他不当商业用途。
  • 使用或者参考本项目即视为同意上述条款,即 “谁使用,谁负责” 。如不同意,请立即停止使用并删除本项目。!!!
http://www.jsqmd.com/news/431730/

相关文章:

  • 急需回收话费卡?教你快速找到靠谱平台! - 团团收购物卡回收
  • 2026年热门的上海螺带混合机/混合机全方位厂家推荐参考 - 行业平台推荐
  • 2026电子半导体与生物医药厂房机电安装工程公司哪家更专业_ - 品牌2026
  • 【2025最新】基于SpringBoot+Vue的Web就业管理系统管理系统源码+MyBatis+MySQL
  • 论文省心了!10个降AIGC软件测评:专科生降AI率必备工具推荐
  • 杉德斯玛特卡回收攻略:回收方式对比及回收流程分享 - 团团收购物卡回收
  • 【2025最新】基于SpringBoot+Vue的Web及游戏管理平台管理系统源码+MyBatis+MySQL
  • Python爬虫实战:Python实现高德地图POI矩形网格全量爬取实战!
  • 建议收藏|更贴合MBA需求的降AIGC软件 千笔·专业降AIGC智能体 VS Checkjie
  • 保温杯推荐南:如何根据生活场景,挑选一款时尚又实用的保温杯? - 速递信息
  • 2026电子半导体生物医药厂房净化管道安装工程公司推荐 - 品牌2026
  • 装修环保板材十大排名是什么? - 十大品牌榜
  • 2026年优质工单系统品牌及厂商推荐,5家靠谱平台实测优选 - 品牌2026
  • 别再瞎找了!一键生成论文工具 千笔·专业论文写作工具 VS 知文AI,专为本科生量身打造!
  • 2026年,成都防水补漏公司哪家好?本地正规公司 资质齐全,免费上门检测(附避坑+选购全指南) - 宁夏壹山网络
  • 摆脱论文困扰! 9个AI论文平台测评:专科生毕业论文+开题报告写作全攻略
  • 改稿速度拉满!实力封神的降AIGC软件 —— 千笔·专业降AI率智能体
  • OpelClaw接入本地基于Ollama的DeepSeek大模型
  • 基于PLC的配送箱升降控制系统的设计硬件设计
  • 2026电子半导体防静电洁净室生物医药无尘室工程公司实力盘点 - 品牌2026
  • 2026年市场调查机构推荐厂家最新推荐:四川做市场调研的公司推荐/四川的市场调研公司推荐/选择指南 - 优质品牌商家
  • 2026年靠谱的干粉搅拌机/上海卧式搅拌机厂家采购参考指南 - 行业平台推荐
  • 2026年金融、电商、教育智能语音机器人厂商推荐及售后指南 - 品牌2026
  • 2026年评价高的钢瓶加热器/桥梁加热器行业内口碑厂家推荐 - 行业平台推荐
  • 【2026最新】MuseScore下载安装全攻略(附安装包+图文步骤) - sdfsafafa
  • 杉德斯玛特卡线上回收值得信赖吗?一文搞懂完整回收流程 - 团团收购物卡回收
  • 2026高标准厂房环保工程公司推荐 生物医药与电子半导体适用 - 品牌2026
  • 2026年市面上靠谱的化粪池清理公司怎么选,优质的化粪池清掏技术实力与市场典范解析 - 品牌推荐师
  • 2026电线电缆回收厂家权威测评排行:正规品牌甄选指南 - 深度智识库
  • 2026变压器回收厂家全国权威测评:合规与服务能力排行 - 深度智识库