Python + django + 騰訊api 取得中國省市區列表
由於最近在建置關於中國物流方面的東西講到物流一定會想到中國非常非常多的省市區
如果用手動新增的情況下你一定會發瘋
所以寫了一個可以自動抓省市區並新增至資料庫的程式
設計架構:
由於中國有分省跟市跟區
不過市有分直轄市跟一般的市
所以在結構上會有一些不一致
比如說
provinces 省
下面有
city 市
在更下面就是
district 區
而資料庫的關聯應該就是
省 關聯 市 關聯 區
不過當直轄市出現的時候
若把它當作省放的話
就會變成
provinces 省
關聯
city 市
不過拿上海市來說好了
上海市下面就已經是區了
這樣table跟資料概念不一
所以我的解決方法是
把直轄市仍放在city當中
並加一個Boolean判斷是否是直轄市
table架構如下
//uq_id指的是各省市區都有一個id
class ChinaProvinces(models.Model): name = models.CharField( pgettext_lazy('china provinces', 'name'), max_length=12) uq_id = models.CharField( pgettext_lazy('china provinces', 'uq_id'), max_length=6, unique=True) enable = models.BooleanField(default="True") sort = models.SmallIntegerField('sort', default=0) def __str__(self): return self.name class ChinaCity(models.Model): //由於前面提到的直轄市並不隸屬於任何省,所以要設定null=True province = models.ForeignKey( ChinaProvinces, related_name='province', blank=True, null=True) name = models.CharField( pgettext_lazy('china city', 'name'), max_length=12) uq_id = models.CharField( pgettext_lazy('china city', 'uq_id'), max_length=6, unique=True) enable = models.BooleanField(default="True") is_municipality = models.BooleanField(default=False) sort = models.SmallIntegerField('sort', default=0) def __str__(self): return self.name class ChinaDistrict(models.Model): city = models.ForeignKey( ChinaCity, related_name='city',) name = models.CharField( pgettext_lazy('china district', 'name'), max_length=12) uq_id = models.CharField( pgettext_lazy('china district', 'uq_id'), max_length=6, unique=True) enable = models.BooleanField(default="True") sort = models.SmallIntegerField('sort', default=0) def __str__(self): return self.name接下來是如何跟騰訊call api取得我們要的資料
首先
先去註冊個QQ帳號吧
註冊完之後去申請金鑰
我們這次要使用的是騰訊web service api (beta)
寫這篇文章的時候他還是beta版
所以之後規格會不會改我不能跟大家保證
他的api route是
http://apis.map.qq.com/ws/district/v1 之後則是參數囉 首先是所有地區的列表
http://apis.map.qq.com/ws/district/v1/list?key=OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77
key後面的那一串就是剛剛申請的金鑰字串
打下來這一包的結構如
可以看到result下面有3筆list
照順序來說是
省.直轄市 市 區接下來就是針對某一個地區的id取
的該地區下一層級的地區列表
http://apis.map.qq.com/ws/district/v1/getchildren? &id=110000& key=OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77
id這個參數帶的就是地區代表碼
這包的結構如下:
實作
先在後台新增我想要自動匯入的省份或直轄市
views.py
import requests
QQ_KEY = "YOUR_KEY"
URL = "http://apis.map.qq.com/ws/district/v1/"
def import_address(request):
def get_district(id):
url = URL + "getchildren?&id=%s&key=%s" % (id, QQ_KEY,)
response = json.loads(requests.get(url=url).text)
return response
def auto_create_from_provinces():
provinces = ChinaProvinces.objects.filter(enable=True).all()
try:
for province in provinces:
provinces_uq_id = province.uq_id
cities = get_district(provinces_uq_id)
for city in cities['result'][0]:
city_uq_id = city["id"]
city_name = city["fullname"]
new_city = ChinaCity(name=city_name, uq_id=city_uq_id, province=province)
new_city.save()
districts = get_district(city_uq_id)
for district in districts['result'][0]:
district_uq_id = district["id"]
district_name = district["fullname"]
new_district = ChinaDistrict(name=district_name, uq_id=district_uq_id, city=new_city)
new_district.save()
except Exception as e:
print(e)
def auto_create_from_municipalities():
municipalities = ChinaCity.objects.filter(enable=True, is_municipality=True).all()
for municipality in municipalities:
municipality_uq_id = municipality.uq_id
districts = get_district(municipality_uq_id)
for district in districts['result'][0]:
district_uq_id = district["id"]
district_name = district["fullname"]
new_district = ChinaDistrict(name=district_name, uq_id=district_uq_id, city=municipality)
new_district.save()
auto_create_from_provinces()
auto_create_from_municipalities()
return HttpResponse("Done!!")
大功告成
訂閱:
張貼留言
(
Atom
)
技術提供:Blogger.
沒有留言 :
張貼留言