Python实现一键下载并整合统计年鉴Excel文件
背景介绍
如果你经常做数据分析、论文写作或数据整理,可能会遇到这样的问题:
统计年鉴官网上有几十甚至上百个 Excel 文件,需要一个个点开下载,还要手动分类整理,非常耗时。
这篇文章要讲的这段 Python 代码,可以帮你:
- 自动抓取网页上的所有 Excel 文件
- 批量下载到本地
- 按文件名前两位数字自动分类
- 自动合并为一个 Excel 文件(每个子类作为一个 Sheet)
- 自动跳过已下载文件,避免重复下载
重要提醒:
本代码仅供学习交流使用。请在合法合规前提下使用,遵守网站数据使用规范和相关法律法规。
代码功能说明
这段代码做了三件事:
第一步:抓取 Excel 下载链接
从指定网页中,自动提取所有 .xls 和 .xlsx 文件链接。
第二步:批量下载
自动下载所有 Excel 文件到本地文件夹。
第三步:自动整合
根据文件名前两位数字进行“大类分类”,生成:
01_年鉴.xlsx
02_年鉴.xlsx
03_年鉴.xlsx
...
每个文件中:
- 不同子类放在不同 sheet 中
- 自动清理非法字符
- 自动跳过空文件
- 自动避免 openpyxl 报错
运行完成后,你会在本地看到:
F:\年鉴
├── 2023
│ ├── excel
│ ├── 01_年鉴.xlsx
│ ├── 02_年鉴.xlsx
├── 2024
运行环境准备
安装 Python
推荐安装 Python 3.9 以上版本。
检查是否已安装:
python --version
创建项目文件夹
例如:
D:\yearbook_project
在该文件夹中新建:
main.py
把下面的代码复制进去。
安装依赖库
打开命令行(Win + R → 输入 cmd),执行:
pip install requests pandas beautifulsoup4 openpyxl
这些库的作用(用大白话解释):
requests:负责“帮你打开网页”beautifulsoup4:负责“从网页里找下载链接”pandas:负责“读取和写入 Excel”openpyxl:负责“生成 Excel 文件”
详细运行步骤
第一步:修改保存路径
找到代码中的:
base_dir = r"F:\年鉴"
修改为你电脑上的路径,例如:
base_dir = r"D:\yearbook_project\data"
注意:必须是存在的磁盘路径。
第二步:保存代码
保存为:
main.py
第三步:运行代码
在项目目录中执行:
python main.py
第四步:观察运行过程
终端会看到类似输出:
[INFO] 2023 年抓取 Excel 链接...
[INFO] 2023 年发现 86 个 Excel 文件
[OK] 下载成功: ...
[OK] 01_年鉴.xlsx 已生成
第五步:验证结果
打开你设置的目录:
D:\yearbook_project\data
你会看到:
- 每个年份一个文件夹
- 每个大类一个整合好的 Excel 文件
打开 Excel,可以看到多个 Sheet。
核心代码解析(新手能看懂版)
下面是完整代码(已去除任何私人信息,可直接运行):
import os
import re
import requests
import pandas as pd
from bs4 import BeautifulSoup
from collections import defaultdict
# ================= 配置 =================
base_dir = r"D:\【your_folder】"
years = [2023, 2024]
base_urls = {
2023: "https://oss.henan.gov.cn/sbgt-wztipt/attachment/hntjj/hntj/lib/tjnj/2023nj/zk/lefte.htm",
2024: "https://oss.henan.gov.cn/sbgt-wztipt/attachment/hntjj/hntj/lib/tjnj/2024nj/zk/indexce.htm"
}
# ================= 工具函数 =================
def get_excel_links(url, year):
"""解析页面,返回所有 Excel 文件的完整 URL 列表"""
try:
resp = requests.get(url, timeout=20)
resp.raise_for_status()
resp.encoding = 'gb2312'
except Exception as e:
print(f"[ERROR] 获取网页失败: {url} ({e})")
return []
soup = BeautifulSoup(resp.text, "html.parser")
links = []
for a in soup.find_all('a', href=True):
href = a['href']
if href.lower().endswith(('.xls', '.xlsx')):
if href.startswith("http"):
links.append(href)
else:
base = f"https://oss.henan.gov.cn/sbgt-wztipt/attachment/hntjj/hntj/lib/tjnj/{year}nj/zk/"
links.append(base + href.lstrip('./'))
return links
def download_file(url, save_path):
"""下载文件,如果已存在则跳过"""
if os.path.exists(save_path) and os.path.getsize(save_path) > 0:
print(f"[SKIP] 已存在: {save_path}")
return
try:
resp = requests.get(url, timeout=30)
resp.raise_for_status()
with open(save_path, 'wb') as f:
f.write(resp.content)
print(f"[OK] 下载成功: {save_path}")
except Exception as e:
print(f"[ERROR] 下载失败: {save_path} ({e})")
def clean_and_merge_by_category(year_folder, output_dir):
excel_files = [f for f in os.listdir(year_folder) if f.lower().endswith(('.xls', '.xlsx'))]
if not excel_files:
print(f"[INFO] 没有 Excel 文件可整合: {year_folder}")
return
category_dict = defaultdict(list)
# 这里是“按文件名前两位分组”
for f in excel_files:
match = re.match(r'(\d{2})(\d{2})', f)
if not match:
print(f"[WARN] 文件名不符合规则,跳过: {f}")
continue
main_cat, sub_cat = match.groups()
category_dict[main_cat].append((f, sub_cat))
os.makedirs(output_dir, exist_ok=True)
for main_cat, files in category_dict.items():
sheets_to_write = []
for fname, sub_cat in files:
path = os.path.join(year_folder, fname)
try:
with pd.ExcelFile(path) as xl:
for sheet_name in xl.sheet_names:
df = xl.parse(sheet_name, header=None)
if df.empty:
continue
sheet_name_clean = re.sub(r'[\\/*?:[\]]', '', sub_cat)[:31]
sheets_to_write.append((df, sheet_name_clean))
except Exception as e:
print(f"[ERROR] 处理 {path} 失败 ({e})")
if not sheets_to_write:
sheets_to_write.append((pd.DataFrame({"提示": ["此大类下无有效数据"]}), "占位"))
output_file = os.path.join(output_dir, f"{main_cat}_年鉴.xlsx")
if os.path.exists(output_file):
os.remove(output_file)
with pd.ExcelWriter(output_file, engine='openpyxl') as writer:
for df, sheet_name_clean in sheets_to_write:
df.to_excel(writer, sheet_name=sheet_name_clean, index=False, header=False)
print(f"[OK] {main_cat}_年鉴.xlsx 已生成")
# ================= 主流程 =================
for year in years:
print(f"\n[INFO] {year} 年抓取 Excel 链接...")
url = base_urls[year]
links = get_excel_links(url, year)
print(f"[INFO] {year} 年发现 {len(links)} 个 Excel 文件")
year_folder = os.path.join(base_dir, str(year), "excel")
os.makedirs(year_folder, exist_ok=True)
for link in links:
fname = os.path.basename(link)
save_path = os.path.join(year_folder, fname)
download_file(link, save_path)
output_dir = os.path.join(base_dir, str(year))
clean_and_merge_by_category(year_folder, output_dir)
print("\n[INFO] 所有年份下载与整合完成!")
用大白话理解核心逻辑
get_excel_links()
可以理解成:“打开网页 → 找到所有下载按钮 → 把 Excel 链接抄下来”
download_file()
可以理解成:“把链接里的文件保存到本地”
并且:
- 如果已经下载过 → 自动跳过
- 避免重复浪费时间
clean_and_merge_by_category()
这是核心。
它做了:
- 找出所有 Excel 文件
- 按文件名前两位数字分组
- 每一组生成一个新的 Excel
- 每个子类作为一个 Sheet
就像:把一堆散乱的资料,自动装进不同文件夹。
常见问题解决
问题1:ModuleNotFoundError
原因:没安装依赖
解决:
pip install requests pandas beautifulsoup4 openpyxl
问题2:下载失败
可能原因:
- 网络问题
- 网站限制
- 被防爬
解决:
- 换网络
- 增加 timeout
- 合法合规使用
问题3:路径报错
例如:
FileNotFoundError
原因:路径不存在
解决:
- 确认磁盘存在
- 不要写错盘符
- 不要有中文空格
问题4:Excel 写入报错
原因:
- 文件正在打开
- openpyxl 未安装
解决:
- 关闭 Excel 再运行
- 安装 openpyxl
总结
这段代码解决了三个核心问题:
- 批量下载
- 自动分类
- 自动整合
适合:
- 数据分析人员
- 写论文的同学
- 做数据研究的人
如果你是新手,只要按照:环境准备 → 安装依赖 → 修改路径 → 运行 → 查看结果
这五步,就能成功跑起来。
再次提醒:请合法合规使用,仅供学习交流。
到此这篇关于Python实现一键下载并整合统计年鉴Excel文件的文章就介绍到这了,更多相关Python下载并整合Excel文件内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
Python OpenCV Canny边缘检测算法的原理实现详解
这篇文章主要介绍了Python OpenCV Canny边缘检测算法的原理实现详解,由于边缘检测对噪声敏感,因此对图像应用高斯平滑以帮助减少噪声,具体详情需要的小伙伴可以参考一下2022-07-07
ROS1 rosbag的详细使用并且使用python合并bag包的方法
这篇文章主要介绍了ROS1 rosbag的详细使用,并且使用python来合并bag包,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下2023-05-05


最新评论