80行Python代码搞定全国区划代码

GitHub源码分享

微信搜索:码农StayUp
主页地址:https://gozhuyinglong.github.io
源码分享:https://github.com/gozhuyinglong/blog-demos

1. 前言

在网站建设中一般会用到全国行政区域划分,以便于做区域数据分析。

下面我们用 Python 来爬取行政区域数据,数据来源为比较权威的国家统计局。爬取的页面为2020年统计用区划代码和城乡划分代码

这里有个疑问,为啥统计局只提供了网页版呢?提供文件版岂不是更方便大众。欢迎了解的小伙伴给我留言。

2. 网站分析

在爬取数据之前要做的便是网站分析,通过分析来判断使用何种方式来爬取。

2.1 省份页面

一个静态页面,其二级页面使用的是相对地址,通过 class=provincetr 的tr元素来定位

省份页面

2.2 城市页面

一个静态页面,其二级页面使用的是相对地址,通过 class=citytr 的tr元素来定位

城市页面

2.3 区县页面

一个静态页面,其二级页面使用的是相对地址,通过 class=countytr 的tr元素来定位

区县页面

2.4 城镇页面

一个静态页面,其二级页面使用的是相对地址,通过 class=towntr 的tr元素来定位

城镇页面

2.5 村庄页面

一个静态页面,没有二级页面,通过 class=villagetr 的tr元素来定位

村庄页面

3. 安装所需库

通过上面的分析,使用爬取静态网页的方式即可。下面是一些必要的库,需要提前安装好:Requests、BeautifulSoup、lxml。

3.1 Requests

Requests 是一个 Python 的 HTTP 客户端库,用于访问 URL 网络资源。

安装Requests库:

pip install requests

3.2 BeautifulSoup

Beautifu lSoup 是一个可以从 HTML 或 XML 文件中提取数据的 Python 库。它能够通过指定的转换器实现页面文档的导航、查找、修改等。

安装 BeautifulSoup 库:

pip install beautifulsoup4

3.3 lxml

lxml 是一种使用 Python 编写的库,可以迅速、灵活地处理 XML 和 HTML。

它支持 XML Path Language (XPath) 和 Extensible Stylesheet Language Transformation (XSLT),并且实现了常见的 ElementTree API。

安装lxml库:

pip install lxml

4. 代码实现

爬虫分以下几步:

  • 使用Requests库来获取网页。
  • 使用BeautifulSoup和lxml库解析网页。
  • 使用Python的File来存储数据。

输出文件为:当前py文件所在目录,文件名称:area-number-2020.txt

输出结果为:级别、区划代码、名称,中间使用制表符分隔,便于存到Exce和数据库中。

下面看详细代码:

# -*-coding:utf-8-*-
import requests
from bs4 import BeautifulSoup


# 根据地址获取页面内容,并返回BeautifulSoup
def get_html(url):
    # 若页面打开失败,则无限重试,没有后退可言
    while True:
        try:
            # 超时时间为1秒
            response = requests.get(url, timeout=1)
            response.encoding = "GBK"
            if response.status_code == 200:
                return BeautifulSoup(response.text, "lxml")
            else:
                continue
        except Exception:
            continue


# 获取地址前缀(用于相对地址)
def get_prefix(url):
    return url[0:url.rindex("/") + 1]


# 递归抓取下一页面
def spider_next(url, lev):
    if lev == 2:
        spider_class = "city"
    elif lev == 3:
        spider_class = "county"
    elif lev == 4:
        spider_class = "town"
    else:
        spider_class = "village"

    for item in get_html(url).select("tr." + spider_class + "tr"):
        item_td = item.select("td")
        item_td_code = item_td[0].select_one("a")
        item_td_name = item_td[1].select_one("a")
        if item_td_code is None:
            item_href = None
            item_code = item_td[0].text
            item_name = item_td[1].text
            if lev == 5:
                item_name = item_td[2].text
        else:
            item_href = item_td_code.get("href")
            item_code = item_td_code.text
            item_name = item_td_name.text
        # 输出:级别、区划代码、名称
        content2 = str(lev) + "\t" + item_code + "\t" + item_name
        print(content2)
        f.write(content2 + "\n")
        if item_href is not None:
            spider_next(get_prefix(url) + item_href, lev + 1)


# 入口
if __name__ == '__main__':

    # 抓取省份页面
    province_url = "http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2020/index.html"
    province_list = get_html(province_url).select('tr.provincetr a')

    # 数据写入到当前文件夹下 area-number-2020.txt 中
    f = open("area-number-2020.txt", "w", encoding="utf-8")
    try:
        for province in province_list:
            href = province.get("href")
            province_code = href[0: 2] + "0000000000"
            province_name = province.text
            # 输出:级别、区划代码、名称
            content = "1\t" + province_code + "\t" + province_name
            print(content)
            f.write(content + "\n")
            spider_next(get_prefix(province_url) + href, 2)
    finally:
        f.close()

5. 资源下载

如果你只是需要行政区域数据,那么已经为你准备好了,从下面连接中下载即可。

链接:https://pan.baidu.com/s/18MDdkczwJVuRZwsH0pFYwQ
提取码:t2eg

6. 爬虫遵循的规则

引自:https://www.cnblogs.com/kongyijilafumi/p/13969361.html

  1. 遵守 Robots 协议,谨慎爬取
  2. 限制你的爬虫行为,禁止近乎 DDOS 的请求频率,一旦造成服务器瘫痪,约等于网络攻击
  3. 对于明显反爬,或者正常情况不能到达的页面不能强行突破,否则是 Hacker 行为
  4. 如果爬取到别人的隐私,立即删除,降低进局子的概率。另外要控制自己的欲望
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,384评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,845评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,148评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,640评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,731评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,712评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,703评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,473评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,915评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,227评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,384评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,063评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,706评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,302评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,531评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,321评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,248评论 2 352

推荐阅读更多精彩内容