Python爬虫实战:手把手教你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)
一句话说明:本文将利用 Python 的
Requests与BeautifulSoup4库,从公益慈善政务信息公开页抓取“项目用途分类目录”,产出结构化的 CSV 与 SQLite 数据库。读完能获得什么:
- 掌握目录型网页的高效解析模板,实现从 HTML 到结构化 Dataframe 的无缝转换。
- 学会处理脏数据清洗(如去除多余空格、统一字符编码)。
- 获得一份可用于公益项目自动分类归因的底层标准化标签库。
1️⃣ 摘要(Abstract)
本文旨在演示如何针对典型的“政务/公示类”静态网页进行信息抽取。我们将构建一个名为Charity_Categorization_Engine的爬虫程序,重点攻克分类目录的提取、用途说明的语义提取及适用对象的关联。最终产出的Charity_Project_Classification.csv将作为构建公益数据中台的元数据核心。
2️⃣ 背景与需求(Why)
为什么要爬取慈善分类?
- 自动化归档:许多慈善组织在发布项目时分类不统一,通过这套标准目录,可以实现 AI 自动贴标。
- 审计合规:在对公益项目进行合规性审查时,需要依据标准目录判定其资金用途是否超范围。
- 信息聚合:为第三方公益搜索平台提供标准化的筛选索引。
目标字段清单(Field Schema):
| 字段名 (Field) | 含义 | 示例 |
|---|---|---|
project_category | 项目类别 | 扶贫济困 / 助学支教 / 环境保护 |
purpose_desc | 用途说明 | 用于资助家庭困难学生的生活补助 |
target_audience | 适用对象 | 18岁以下学龄儿童、偏远地区学校 |
remarks | 备注 | 需提供贫困证明、定期回访 |
3️⃣ 合规与注意事项(必写)
作为一名有情怀的爬虫爱好者,我们必须守护互联网生态的温度:
- Robots.txt:大多数公益公示页允许抓取,但禁止将数据用于恶意欺诈或非法商业牟利。
- 频率控制:慈善类站点通常资源有限,我们应严格限制并发,设置
DOWNLOAD_DELAY,不给服务器添乱。🙏 - 敏感信息:我们仅采集**“规则与目录”**,绝对不采集任何捐赠者、受助者的个人隐私数据。
4️⃣ 技术选型与整体流程(What/How)
类型:静态页面抓取(Static HTML Scraping)。
工具链:
Requests: 负责发送网络请求。BeautifulSoup4: 负责 DOM 树的解析与节点搜索。Pandas: 负责数据的清洗、转换与持久化。
流程:[请求页面] → [定位分类块] → [循环提取行] → [字段清洗] → [导出存储]
5️⃣ 环境准备与依赖安装(可复现)
Python 版本:3.9或更高版本。
项目目录结构:
Charity_Project_Scraper/ ├── core/ │ ├── __init__.py │ ├── fetcher.py # 网络请求模块 │ └── parser.py # 核心解析算法 ├── data/ # 存储产出的 CSV/DB ├── main.py # 程序总入口 └── requirements.txt # 依赖库清单安装命令:
pipinstallrequests beautifulsoup4 pandas loguru lxml6️⃣ 核心实现:请求层(Fetcher)
我们不仅要发请求,还要发得“像人”,发得“稳健”。
importrequestsfromloguruimportloggerimportrandomimporttimeclassCharityFetcher:def__init__(self):# 模拟真实浏览器,避免被拦截self.headers={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36","Accept-Language":"en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7"}self.timeout=15defget_html(self,url:str,retries:int=3):""" 具备自动重试机制的页面抓取 """foriinrange(retries):try:# 随机延迟,尊重服务器time.sleep(random.uniform(1.0,3.0))response=requests.get(url,headers=self.headers,timeout=self.timeout)response.raise_for_status()# 4xx/5xx 会抛出异常# 自动处理中文编码response.encoding=response.apparent_encoding logger.info(f"✅ Success: Fetched{url}")returnresponse.textexceptExceptionase:logger.warning(f"⚠️ Attempt{i+1}failed for{url}:{e}")ifi==retries-1:logger.error(f"❌ Permanent failure for{url}")returnNone7️⃣ 核心实现:解析层(Parser)
针对目录型页面,我们通常需要处理 HTML 里的<ul>或者<table>。这里我们演示如何处理嵌套结构。
frombs4importBeautifulSoupimportreclassCharityParser:def__init__(self,html:str):self.soup=BeautifulSoup(html,'lxml')defparse_directory(self):""" 核心逻辑:解析分类目录 """results=[]# 寻找包含“分类”关键字的容器# 实际开发中根据 F12 定位具体的 class 或 iditems=self.soup.find_all('div',class_='charity-item')foriteminitems:# 1. 提取类别名 (通常在 h4 或 strong 标签)cat_tag=item.find(['h4','strong'])category_name=cat_tag.get_text(strip=True)ifcat_tagelse"Uncategorized"# 2. 提取详细说明内容full_content=item.get_text(separator='|',strip=True)# 使用简单的正则或字符串切分提取特定字段# 假设格式是:用途说明:xxx | 适用对象:yyy | 备注:zzzpurpose=self._extract_field(full_content,"用途说明")audience=self._extract_field(full_content,"适用对象")remarks=self._extract_field(full_content,"备注")results.append({"project_category":category_name,"purpose_desc":purpose,"target_audience":audience,"remarks":remarks})returnresultsdef_extract_field(self,text:str,field_name:str)->str:"""从混合文本中抠出目标字段内容"""pattern=f"{field_name}[::](.*?)(?=\\||$)"match=re.search(pattern,text)returnmatch.group(1).strip()ifmatchelse"N/A"8️⃣ 数据存储与导出(Storage)
我们要实现一键导出 CSV,并建立 SQLite 数据库,方便后续进行 SQL 查询。
importpandasaspdimportsqlite3classCharityStorage:@staticmethoddefsave(data:list,base_filename:str):ifnotdata:logger.error("No data available to save.")returndf=pd.DataFrame(data)# 1. 导出 CSV (English filename as requested)csv_filename=f"{base_filename}.csv"df.to_csv(csv_filename,index=False,encoding='utf-8-sig')logger.success(f"💾 Data exported to{csv_filename}")# 2. 存储至 SQLite 数据库db_filename=f"{base_filename}.db"conn=sqlite3.connect(db_filename)df.to_sql('charity_catalog',conn,if_exists='replace',index=False)conn.close()logger.success(f"💾 Database updated:{db_filename}")9️⃣ 运行方式与结果展示(必写)
启动命令:
python main.py示例运行结果:
| project_category | purpose_desc | target_audience | remarks |
|---|---|---|---|
| 应急救援 | 用于重大灾害期间的物资采购及救援队补贴 | 受灾群众、一线救援人员 | 紧急状态下优先拨付 |
| 疾病救助 | 资助大病患者的医疗费、康复费 | 困难家庭重大疾病患者 | 需凭医院诊断证明 |
| 乡村振兴 | 投入农村基础设施建设、农技培训 | 脱贫地区村民、基层干部 | 需配合当地政府执行 |
🔟 常见问题与排错(强烈建议写)
作为一名过来人,这些坑你要提前避开:💪
Q: 403 Forbidden 报错?
- A:对方可能有简单的防盗链或 UA 识别。请确保你的
User-Agent与浏览器一致,或者尝试添加Referer。
- A:对方可能有简单的防盗链或 UA 识别。请确保你的
Q: HTML 抓取下来是乱码?
- A:政务网常有 GBK 编码。在代码中使用
response.encoding = response.apparent_encoding即可完美解决。
- A:政务网常有 GBK 编码。在代码中使用
Q: 目录是展开式的,点击后才加载内容?
- A:这说明是动态渲染。你需要打开浏览器 F12 找到 Network 里的 XHR 请求,直接抓取 JSON 接口。如果真的必须模拟点击,建议使用
Playwright。
- A:这说明是动态渲染。你需要打开浏览器 F12 找到 Network 里的 XHR 请求,直接抓取 JSON 接口。如果真的必须模拟点击,建议使用
1️⃣1️⃣ 进阶优化(可视化展示)
为了让这份数据更有价值,我们来生成一份分类分布图(全英文显示)。
importmatplotlib.pyplotaspltdefgenerate_visual_report(csv_path:str):df=pd.read_csv(csv_path)# 统计分类数量 (模拟示例)category_counts=df['project_category'].value_counts()plt.figure(figsize=(10,6))category_counts.plot(kind='bar',color='emerald')# Text elements must be in Englishplt.title("Distribution of Charity Project Categories",fontsize=15)plt.xlabel("Category Names",fontsize=12)plt.ylabel("Frequency",fontsize=12)plt.xticks(rotation=45)plt.tight_layout()# Save chart with English nameplt.savefig("Charity_Data_Analysis.png")logger.success("📊 Visualization report generated: Charity_Data_Analysis.png")1️⃣2️⃣ 总结与延伸阅读
- 复盘:我们从零搭建了一个稳健的慈善分类采集引擎,学会了处理目录型页面的逻辑抽取。
- 下一步:你可以尝试将这些数据接入到你的Django 或 Flask 后端项目,做一个公益知识搜索库。或者使用
Scrapy框架重写它,实现多页并发抓取!
🌟 文末
好啦~以上就是本期的全部内容啦!如果你在实践过程中遇到任何疑问,欢迎在评论区留言交流,我看到都会尽量回复~咱们下期见!
小伙伴们在批阅的过程中,如果觉得文章不错,欢迎点赞、收藏、关注哦~
三连就是对我写作道路上最好的鼓励与支持!❤️🔥
✅ 专栏持续更新中|建议收藏 + 订阅
墙裂推荐订阅专栏 👉 《Python爬虫实战》,本专栏秉承着以“入门 → 进阶 → 工程化 → 项目落地”的路线持续更新,争取让每一期内容都做到:
✅ 讲得清楚(原理)|✅ 跑得起来(代码)|✅ 用得上(场景)|✅ 扛得住(工程化)
📣想系统提升的小伙伴:强烈建议先订阅专栏 《Python爬虫实战》,再按目录大纲顺序学习,效率十倍上升~
✅ 互动征集
想让我把【某站点/某反爬/某验证码/某分布式方案】等写成某期实战?
评论区留言告诉我你的需求,我会优先安排实现(更新)哒~
⭐️ 若喜欢我,就请关注我叭~(更新不迷路)
⭐️ 若对你有用,就请点赞支持一下叭~(给我一点点动力)
⭐️ 若有疑问,就请评论留言告诉我叭~(我会补坑 & 更新迭代)
✅ 免责声明
本文爬虫思路、相关技术和代码仅用于学习参考,对阅读本文后的进行爬虫行为的用户本作者不承担任何法律责任。
使用或者参考本项目即表示您已阅读并同意以下条款:
- 合法使用: 不得将本项目用于任何违法、违规或侵犯他人权益的行为,包括但不限于网络攻击、诈骗、绕过身份验证、未经授权的数据抓取等。
- 风险自负: 任何因使用本项目而产生的法律责任、技术风险或经济损失,由使用者自行承担,项目作者不承担任何形式的责任。
- 禁止滥用: 不得将本项目用于违法牟利、黑产活动或其他不当商业用途。
- 使用或者参考本项目即视为同意上述条款,即 “谁使用,谁负责” 。如不同意,请立即停止使用并删除本项目。!!!
