Python爬虫实战:手把手教你如何采集灌区基础信息公开页!
2026/5/23 9:12:08 网站建设 项目流程

㊗️本期内容已收录至专栏《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)

  • 本文目标:利用 Python 的requests+lxml库,从灌区信息公开页抓取完整的名录信息,并重点解决“面积单位”和“建设时间”的自动化归一化问题。

  • 读完收益

    1. 掌握XPath 定位嵌套表格的万能公式。
    2. 学会利用正则表达式(Regex)优雅地进行单位换算与数值提取。
    3. 产出一份干净、可直接用于计算的结构化灌区数据集。

1️⃣ 摘要(Abstract)

  • 项目概况:本项目针对灌区基础信息公开页,通过封装请求与解析模块,实现对灌区名、流域、面积、地区等 5 个维度的自动化采集。
  • 技术亮点:重点攻克文本型数值的“脱壳”与单位转换。
  • 核心收获:掌握规则型名录抓取全流程,提升数据清洗(Data Cleaning)的工程化思维。

2️⃣ 背景与需求(Why)

  • 为什么要爬

    • 水资源分析:评估不同流域的农业灌溉压力。
    • 历史演变研究:分析不同年代建设灌区的分布规律。
    • 自动化整合:将原本需要手动翻页、复制的表格数据瞬间转化为 Excel。
  • 目标字段清单

    • 灌区名 (District Name)
    • 流域 (Basin)
    • 设计灌溉面积 (Design Area) ——清洗重点
    • 地区 (Region)
    • 建设时间 (Construction Time) ——格式归一化

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

  1. robots.txt:此类站点通常属于公益性信息公开,遵守基础抓取协议。
  2. 频率控制:建议设置1s 左右的抓取间隔。我们要像春雨润物细无声,不要给对方服务器造成压力。
  3. 合规声明:一切以技术分享和学术分析为主,不涉及非公开敏感信息,不绕过登录限制。

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

  • 技术栈:静态解析流(Static Scraper)。
  • 选型理由:灌区页面多为传统的服务端渲染,结构稳定。使用lxml配合 XPath 的解析速度极快,且代码可读性极佳。
  • 逻辑流程
    采集 (Fetcher)解析 (XPath Extraction)清洗 (Unit Normalization)存储 (CSV)

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

  • Python 版本:3.10+

  • 依赖安装

    pipinstallrequests lxml pandas
  • 推荐项目目录

    irrigation_project/ ├── main.py # 逻辑入口 ├── data_cleaner.py # 核心清洗工具函数 └── irrigation_basic_info.csv # 最终产出数据

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

我们需要一个稳健的请求头,防止被误判。

importrequestsdeffetch_irrigation_html(url):headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Irrigation-Data-Bot/1.0','Accept':'text/html,application/xhtml+xml,xml;q=0.9','Connection':'keep-alive'}try:response=requests.get(url,headers=headers,timeout=15)response.raise_for_status()# 很多老站点用的是 gbk,建议自动识别response.encoding=response.apparent_encodingreturnresponse.textexceptExceptionase:print(f"❌ Oops, failed to link:{e}")returnNone

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

实战重点(单位清洗逻辑):这是最展现基本功的地方。

fromlxmlimportetreeimportredefclean_area(text):""" 清洗面积字段:将 '12.5万亩' 或 '800公顷' 统一转为 '亩' (mu) """ifnottext:return0.0# 提取数字(含小数点)num_match=re.search(r'\d+\.?\d*',text.replace(',',''))ifnotnum_match:return0.0val=float(num_match.group())if'万'intext:val*=10000if'公顷'intext:val*=15# 1公顷 = 15亩returnround(val,2)defparse_irrigation_table(html):tree=etree.HTML(html)# 定位表格中的数据行rows=tree.xpath('//table[@class="data-list"]//tr[position()>1]')records=[]forrowinrows:tds=row.xpath('./td')iflen(tds)<5:continueraw_area="".join(tds[2].xpath('.//text()')).strip()records.append({'district_name':"".join(tds[0].xpath('.//text()')).strip(),'basin':"".join(tds[1].xpath('.//text()')).strip(),'design_area_mu':clean_area(raw_area),# 这里的清洗是灵魂'region':"".join(tds[3].xpath('.//text()')).strip(),'construction_year':re.search(r'\d{4}',"".join(tds[4].xpath('.//text()'))).group()ifre.search(r'\d{4}',"".join(tds[4].xpath('.//text()')))else"Unknown"})returnrecords

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

导出为 CSV。文件名为:irrigation_districts_basic_info.csv

  • 字段映射表
Field (En)TypeExample
district_nameStringDujiangyan (都江堰)
basinStringMin River (岷江)
design_area_muFloat11300000.0
regionStringSichuan Province
construction_yearString1950

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

  • 运行命令python main.py

  • 结果展示

    district_name,basin,design_area_mu,region,construction_year "Dujiangyan","Min River",11300000.0,"Sichuan",1950 "Hetao Irrigation","Yellow River",10000000.0,"Inner Mongolia",1960

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

  1. Q: 拿到的面积是 0?

    • A:检查你的正则是否漏掉了带逗号的数字(如1,250)。我在代码里加了replace(',', '')来兼容。
  2. Q: 表格跨行导致数据错位?

    • A:很多灌区名录有合并单元格。你可以先用item.xpath('normalize-space(.)')这种方式预处理整行文本。
  3. Q: 建设时间写的是“清代”或者“汉代”?

    • A:这种情况正则\d{4}会失效,建议在清洗函数中增加一个if "代" in text: return text的特殊判断逻辑。

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

  • 数据可视化(Visualizations)
    如果抓取完数据,你可以用 Matplotlib 生成一个图表。请确保使用英文标注。

    • Title: “Distribution of Irrigation Areas by Basin”
    • X-axis: “Basin Name”
    • Y-axis: “Total Area (Million Mu)”
  • 并发提升:使用ThreadPoolExecutor开启 4-8 个线程并行处理多个页面,效率翻倍!⚡️

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

  • 复盘:今天我们攻克了灌区名录抓取中最核心的“单位归一化”问题,这是一切数据分析的基础。
  • 下一步:如果你想更进一步,可以尝试抓取灌区渠道的地理矢量数据,那会涉及到更复杂的地理空间解析逻辑!

🌟 文末

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

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

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

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

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

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

✅ 互动征集

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

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


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


✅ 免责声明

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

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

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询