教你从txt文件中提取json格式的省市区数据

伟大的国家统计局为我们提供了省市区的信息[1],可惜不是json格式的,并不能真正用起来。为了得到我们所需要格式化的数据,笔者开发了一个将txt格式的省市区转化为json格式的python脚本。(结尾有小惊喜哦 _

操作系统:ubuntu mate[2],python版本:python3.4,编辑器:pluma。

国家统计局网站上的省市区信息,代码中都没有层级结构,用BeautifulSoup[3]解析也是浪费时间,笔者直接把它复制粘贴到了city.txt中。

下面开始开发脚本:

定义模型

省市区本身就是三个现成的对象,不难想到:

# province of china
class Province:
    def __init__(self, code, name):
        self.code = code
        self.name = name

# city of province
class City:
    def __init__(self, code, name):
        self.code = code
        self.name = name

# coutry of city
class Country:
    def __init__(self, code, name):
        self.code = code
        self.name = name

对于省市而言,它们还有各自的下属行政区,所以要加上一个sub属性来把它们的下属囊括进来。

class Province:
    def __init__(self, code, name):
        # ...
        self.sub = []

class City:
    def __init__(self, code, name):
        # ...
        self.sub = []

这样,我们的省市区模型就算初步定义完成了。

创建方法

有了模型还不够,只有加上合适的方法,才能显示出面向对象的优势。
我们需要一个返回对象的方法 __repr__(),这是一个常见的方法,只要我们提供对象的名称,就能返回必要的对象信息,便于开发和调试。

class Province:
    # ...
    def __repr__(self):
        return '''{"code":%r ,"name": %r, "sub":%r}\n''' % (self.code, self.name, self.sub)

class City:
    # ...
    def __repr__(self):
        return '''{"code":%r ,"name": %r, "sub":%r}\n''' % (self.code, self.name, self.sub)

class Country:
    # ...
    def __repr__(self):
        return '''{"code":%r, "name": %r}\n''' % (self.code, self.name)

当所有的省级行政区构建完成时,输出这个对象的字符串形式就是最终的json数据。为了保证json的格式,我们的 __repr__() 方法是自定义的,输出的结果既没有类的名称,也没有 用<> 括起来。

为了构建一个完整的省市级行政区,我们还需要一种归属的方法,将下属市和区加到sub数组里。可以用数组的 append() 方法来实现:

class Province:
    # ...
    def consist(self, city):
        self.sub.append(city)

class City:
    # ...
    def consist(self, country):
        self.sub.append(country)

此外,还需要一个函数来判断行政区的等级。简单观察一下city.txt,就不难找到这个规律。

所有的省级行政区的代码结尾都是 0000,所有的地级市的代码结尾都是 00,其它都是区县级的行政区划。

举个栗子:江苏的代码是:320000,南京的代码是:320100,秦淮区的代码是:320104。

所以,笔者写了一个根据结尾的0来判定级别的方法:

# judge the type by code
def zero(n):
    i = 1
    if n <= 0:
        return 0
    while n % i == 0:
        i *= 10
    return i/10

解析文本

接下来,就按行读取city.txt中的数据,简单粗暴见效快。

def get_data(filename):
    arr = []
    # open the city.txt
    with open(filename, "r", encoding="utf-8") as read:
        print("file has been open.")
        for line in read:
            arr.append(line.strip())
    print("reading finished")
    return arr

这里唯一值得注意的是:city.txt的编码是什么,打开文件指定的编码就是什么。这里的编码是:utf-8。

输出json

还是要观察city.txt,除了省级行政区是顶行的,其它的都有数量不等的空格。get_data() 方法得到的实际上是一个数组,其中的元素是类似这样110100 市辖区。从中我们也可以看到空格的存在。空格的utf-8编码是 \u3000,使用 strip("\u3000") 来除去首尾的空格。然后将数字保存为code,有效字符保存为name。然后根据 zero() 方法返回的结果构建相应的对象。最后将省级的对象输出就得到了省市区json数据。

最后,揭晓这个小惊喜:源代码和抓取到的json数据可以到我的 github 上获取。链接:https://github.com/zhancongc/city_parse

附录

  1. 统计局网址:http://www.stats.gov.cn/tjsj/tjbz/xzqhdm/201703/t20170310_1471429.html
  2. 本程序在ubuntu mate下运行正常,输出正常;window 10下运行,输出的中文会乱码,原因尚不明确。
  3. Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库。它能够通过你喜欢的转换器实现惯用的文档导航、查找、修改文档的方式。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容