Python爬取国家统计局最新行政区划代码和城乡划分代码

Python爬取国家统计局最新行政区划代码和城乡划分代码

0、前言

国家数据,慎爬!!!

因业务开发需要获取最新的全国省市区行政区划代码,特整理此代码用于抓取最新的全国省市区行政区划代码。

1、数据来源

数据来源于 国家统计局2023年度全国统计用区划代码和城乡划分代码

在这里插入图片描述

2、python代码

import re
import urllib.request
import pandas as pd

INDEX_URL = "https://www.stats.gov.cn/sj/tjbz/tjyqhdmhcxhfdm/2023/"

id_counter = 1
all_data = []
province_id_map = {}
city_id_map = []


def get_province_code():
    global id_counter
    # 获取省级初始页
    province_response = urllib.request.urlopen(INDEX_URL + "index.html").read().decode("utf-8")
    # 获取省份名称+城市初始页数据
    province_data = re.findall(r"<td><a href=\"(.*?)\">(.*?)<br /></a></td>", province_response)
    # 获取城市名称 + 省份代码 + 城市代码
    for url, name in province_data:
        # 省份代码,取前6位并补0
        province_code = url.replace(".html", "") + "000000"
        # 省级 level 为 1,parent_id 为 null
        all_data.append([id_counter, name, province_code[:6], 1, "null"])
        print(f"省: {id_counter}, {name}, {province_code[:6]}, 1, null")  # 打印日志
        province_id_map[province_code[:6]] = id_counter
        province_id = id_counter
        id_counter += 1
        # 获取该省份下的城市和区县
        get_city_code(url, province_id, name)


def get_city_code(province_url, province_id, province_name):
    global id_counter
    # 获取城市初始页
    city_response = urllib.request.urlopen(INDEX_URL + province_url).read().decode("utf-8")
    # 获取城市名称+城市code+地区初始页数据
    city_data = re.findall(r"<tr class=\"citytr\"><td><a href=\"(.*?)\">(.*?)</a></td><td><a href=\"(.*?)\">("
                           r".*?)</a></td></tr>", city_response)

    # 如果是直辖市的情况(只有一个市级行政单位且包含“市辖区”)
    if len(city_data) == 1 and "市辖区" in city_data[0][3]:
        # 对于市辖区,使用省名称,但编码使用市辖区自身的编码
        city_id = id_counter
        # 市级 level 为 2
        all_data.append([city_id, province_name, city_data[0][1][:6], 2, province_id])  # 使用省名称和市辖区编码
        # print(f"市辖区处理,使用省名称: {province_name}, 但使用市辖区编码: {city_data[0][1][:6]}, 2, {province_id}")  # 打印日志
        print(f"市: {id_counter}, {province_name}, {city_data[0][1][:6]}, 2, {province_id}")  # 打印日志
        id_counter += 1
        # 获取区县
        get_area_code(city_data[0][0], city_id)
    else:
        # 正常处理市和区
        for url, city_code, _url, city_name in city_data:
            city_code = city_code[:6]  # 城市代码取前6位
            # 市级 level 为 2
            all_data.append([id_counter, city_name, city_code, 2, province_id])
            print(f"市: {id_counter}, {city_name}, {city_code}, 2, {province_id}")  # 打印日志
            city_id_map.append(city_code)
            city_id = id_counter
            id_counter += 1
            # 获取区县
            get_area_code(url, city_id)


def get_area_code(city_url, city_id):
    global id_counter
    # 获取区县初始页
    area_response = urllib.request.urlopen(INDEX_URL + city_url).read().decode("utf-8")
    # 获取区县名称+区县code+街道初始页数据
    area_data = re.findall(r"<tr class=\"countytr\"><td><a href=\"(.*?)\">(.*?)</a></td><td><a href=\"(.*?)\">("
                           r".*?)</a></td></tr>", area_response)
    for url, district_code, _url, district_name in area_data:
        district_code = district_code[:6]  # 区县代码取前6位
        # 区县 level 为 3
        all_data.append([id_counter, district_name, district_code, 3, city_id])
        print(f"区: {id_counter}, {district_name}, {district_code}, 3, {city_id}")  # 打印日志
        id_counter += 1


def generate_sql(data):
    """
    生成SQL语句并保存到sql.txt文件中
    :param data: 所有爬取的省市区数据
    """
    with open("./省市区行政代码/sql.txt", "w", encoding="utf-8") as f:
        # 写建表语句
        f.write("""
        CREATE TABLE area (
            id INT PRIMARY KEY,
            name VARCHAR(255),
            code CHAR(6),
            level TINYINT,
            parent_id INT
        );
        """)
        # 写插入数据的SQL语句
        for row in data:
            id_, name, code, level, parent_id = row
            insert_sql = f"INSERT INTO area (id, name, code, level, parent_id) VALUES ({id_}, '{name}', '{code}', {level}, {parent_id if parent_id != 'null' else 'NULL'});\n"
            f.write(insert_sql)


def main():
    """
    主启动函数
    :return:
    """
    get_province_code()
    columns = ['id', 'name', 'code', 'level', 'parent_id']
    df = pd.DataFrame(all_data, columns=columns)
    df.to_csv("./省市区行政代码/code.csv", index=False)

    # 生成SQL语句并输出到sql.txt
    generate_sql(all_data)


if __name__ == "__main__":
    main()

3、数据格式

生成的数据包括一个csv文件和一个sql.txt文件。

1.csv文件格式如下:

在这里插入图片描述

2.sql.txt文件如下(可直接执行):

在这里插入图片描述

4、总结

此python代码已尽可能通用,但可能还需要根据具体的业务需求,对代码进行微调。在使用过程中可以根据具体的业务需要对代码和生成的sql语句进行调整。


欢迎随时沟通交流~

  • 7
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

shy好好学习

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值