Python:从 Wikipedia 按大洲获取国家
问题:
你需要一个按大洲排序的国家列表,在宽松许可下。
解决方案
一种可能性是使用 Wikipedia 的数据并从 Wikitext 格式解析信息。例如,英文维基百科"按大洲排列的主权国家和附属领土列表"提供了很好的来源。
此处提供的脚本无需任何外部依赖(仅 Python 核心库)即可下载和解析该格式。需要 Python 2.7+。国家列表以 Unicode 编码。
更新 1.1 2015-12-14: 升级到 Python3,添加文件头 更新 1.2 2017-02-19: 修复更改的格式
countries_by_continent.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
从 Wikipedia 提取按大洲分组的国家列表
"""
__copyright__ = "Copyright (c) 2015 Uli Köhler"
__license__ = "Apache License v2.0"
__version__ = "1.2"
try:
import urllib.request as urllib2
except ImportError:
import urllib2
import re
def downloadWikipediaCountryList():
"""以 wikitext 格式下载 wikipedia 国家列表"""
url = "http://en.wikipedia.org/wiki/List_of_sovereign_states_and_dependent_territories_by_continent?action=raw"
wikitext = urllib2.urlopen(url).read().decode("utf-8")
return wikitext.split("\n")
def splitListAtIndices(theList, indices):
"""
在给定的一组索引处分割列表
>>> splitListAtIndices([1,3,5,7,9], [0, 3])
[[], [1, 3, 5], [7, 9]]
"""
return [theList[i:j] for i, j in zip([0] + indices, indices + [None])]
def extractContinents(wikitextLines):
"""给定 wikitext 格式的行列表,为每个大洲提取属于该大洲的行"""
continentRegex = re.compile("==\s*(\w+)\s*==")
#生成(行索引,大洲)元组列表
continents = [(idx, continentRegex.match(line).group(1))
for idx, line in enumerate(wikitextLines) if continentRegex.match(line)]
continentLines = splitListAtIndices(wikitextLines, [continent[0] for continent in continents])[1:]
return {continents[i][1]: continentLines[i] for i in range(len(continents))}
countryRegex = re.compile("\| '+\[?\[?([^\]]+)\]?\]?\'+")
def findCountry(line):
"""
>>> findCountry("| '''[[Germany]]'''")
'Germany'
>>> findCountry("| [[Berlin]]")
"""
match = countryRegex.match(line)
if match:
country = match.group(1)
if "De facto" in country:
return None
if "|" in country:
return country.partition("|")[2]
return country
return None
def extractCountries(linesByContinent):
return {continent: [findCountry(line) for line in continentLines if findCountry(line)]
for continent, continentLines in linesByContinent.items()}
def getCountriesFromWikipedia():
lines = downloadWikipediaCountryList()
linesByContinent = extractContinents(lines)
return extractCountries(linesByContinent)
if __name__ == "__main__":
#单元自测
import doctest
doctest.testmod()
#打印国家列表
print(getCountriesFromWikipedia())Check out similar posts by category:
Python
If this post helped you, please consider buying me a coffee or donating via PayPal to support research & publishing of new posts on TechOverflow