python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > Python下载并整合Excel文件

Python实现一键下载并整合统计年鉴Excel文件

作者:Laurentianelle

这篇文章主要为大家详细介绍了如何使用Python实现一键下载并整合统计年鉴Excel文件,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下

背景介绍

如果你经常做数据分析、论文写作或数据整理,可能会遇到这样的问题:

统计年鉴官网上有几十甚至上百个 Excel 文件,需要一个个点开下载,还要手动分类整理,非常耗时。

这篇文章要讲的这段 Python 代码,可以帮你:

重要提醒:

本代码仅供学习交流使用。请在合法合规前提下使用,遵守网站数据使用规范和相关法律法规。

代码功能说明

这段代码做了三件事:

第一步:抓取 Excel 下载链接

从指定网页中,自动提取所有 .xls.xlsx 文件链接。

第二步:批量下载

自动下载所有 Excel 文件到本地文件夹。

第三步:自动整合

根据文件名前两位数字进行“大类分类”,生成:

01_年鉴.xlsx
02_年鉴.xlsx
03_年鉴.xlsx
...

每个文件中:

运行完成后,你会在本地看到:

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

这些库的作用(用大白话解释):

详细运行步骤

第一步:修改保存路径

找到代码中的:

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,可以看到多个 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()

这是核心。

它做了:

  1. 找出所有 Excel 文件
  2. 按文件名前两位数字分组
  3. 每一组生成一个新的 Excel
  4. 每个子类作为一个 Sheet

就像:把一堆散乱的资料,自动装进不同文件夹。

常见问题解决

问题1:ModuleNotFoundError

原因:没安装依赖

解决:

pip install requests pandas beautifulsoup4 openpyxl

问题2:下载失败

可能原因:

解决:

问题3:路径报错

例如:

FileNotFoundError

原因:路径不存在

解决:

问题4:Excel 写入报错

原因:

解决:

总结

这段代码解决了三个核心问题:

  1. 批量下载
  2. 自动分类
  3. 自动整合

适合:

如果你是新手,只要按照:环境准备 → 安装依赖 → 修改路径 → 运行 → 查看结果

这五步,就能成功跑起来。

再次提醒:请合法合规使用,仅供学习交流。

到此这篇关于Python实现一键下载并整合统计年鉴Excel文件的文章就介绍到这了,更多相关Python下载并整合Excel文件内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文