龙空技术网

精准到村落的官方地域数据,Python一键搞定(已开源)

麦可易特网 145

前言:

现时朋友们对“mysql省份”都比较讲究,咱们都需要学习一些“mysql省份”的相关文章。那么小编同时在网摘上收集了一些关于“mysql省份””的相关文章,希望你们能喜欢,咱们一起来学习一下吧!

日常的开发中,总是避免不了一些地域的选择,省份城市等没有那么精细的地域选择,很容易能找到,但如果想要更加精准的,比如到村级别的地域信息,就比较难找到现成可用的。想着要不就自己“整理”一份出来,一劳永逸,往后也都用得上。自然而然地,就想到了Python 来“获取”官方的地域数据(也只有官方的才是最权威的),着手试试!

Python

动态代理

不使用代理,“获取”请求很快就会达到上限,被官方给限制了,后续的动作也就没办法开展了,我选了个比较热门的免费代理:

# 获取动态代理IP列表def getIpList():    print(' ------------------ ( START ) 动态代理IP ( ' + getTime() + ' ) ------------------\n')    proxyStime = int(time.time())    ipList = []    for k in range(proxyPageSize):        proxyPageNum = str(proxyPageStart + k)        print(' 开始获取动态代理IP ( 第 ' + proxyPageNum + ' 页 )', end = '')        soupIpPage = getPageInfo(proxyUrl + proxyPageNum)        ips = soupIpPage.findAll(re.compile('tr'))        for i in ips:            tds = i.findAll(re.compile('td'))            if(len(tds) > 0):                for inx, k in enumerate(tds):                    if inx == 1:                        ip = k.text                    if inx == 2:                        port = k.text                    if inx == 5:                        protocol = k.text.lower()                        break                if protocol == 'https':                    ipList.append({                        'port': protocol,                        'addr': protocol + '://' + ip + ':' + port                    })        print(' - 解析成功\n')    return ipList

获取代理 IP

页面数据

官方最新数据,截止 2019年12月31日的最新规划,尝试采用代理 IP 请求页面内容。

# 根据URL获取网站信息def getPageInfo(url, encoding = ''):    page = ''    tryNum = 0    for i in range(tries):        try:            if proxies == '':                response = requests.get(url, headers = proxyHeaders, timeout = 5)            else:                response = requests.get(url, headers = proxyHeaders, proxies = proxies, timeout = 10)            if encoding != '':                response.encoding = encoding            if response.status_code == 200:                page = BeautifulSoup(response.text, 'html.parser')                break        except:            tryNum += 1            print(' ( \033[0;31;40mERROR\033[0m ) 链接访问超时,再次尝试获取信息 ( ' + getTime() + ' )\n')            if tryNum >= 5:                proxies = getRandomIp()                print(' ( \033[0;33;40mNOTICE\033[0m ) 随机选取动态代理IP:\033[0;35;40m' + proxies['https'] + '\033[0m\n')    return page

获取页面内容

解析省份数据

解析列表内容中,统一的 provincetr 样式类名,再往下搜索 a 链接。

# 获取省份链接信息并保存def saveProvinceLink():    print(' ------------------ ( START ) \033[0;31;40m省份链接\033[0m ( ' + getTime() + ' ) ------------------\n')    province = []    file = linkPath + provinceFileName    global totalNumber    global provinceTotalNum    with open(file, 'r+', encoding = 'utf-8') as handler:        try:            data = json.load(handler)            success = False            if forceRefresh or len(data) <= 0:                page = getPageInfo(baseUrl + 'index.html', 'gbk')                if page == '':                    success = True                provinces = page.findAll(name = 'tr', attrs = {'class': re.compile('provincetr')})                for i in provinces:                    links = i.findAll(name = 'a')                    for k in links:                        provinceLink = baseUrl + k['href']                        provinceName = k.text                        print(' \033[0;31;40m' + provinceName + '\033[0m', end = ' ')                        info = {                            'name': provinceName,                            'url': provinceLink                        }                        province.append(info)                    provinceTotalNum += 1                if len(province) > 0:                    totalNumber += + len(province)                    handler.seek(0)                    saveJsonInfo(province, handler)            else:                totalNumber = totalNumber + len(data)                print(' ( \033[0;33;40mNOTICE\033[0m ) 省份链接信息已存在,默认未设置强制更新 ( 可在代码内修改 forceRefresh 值 ) ', end = '')        except:            traceback.print_exc()            if not success:                print(' \n( \033[0;31;40mERROR\033[0m ) 省份链接信息已存在,但内容存在错误,请检查 ( ' + file + ' )', end = '')            else:                print(' \n( \033[0;31;40mERROR\033[0m ) 3次尝试获取省份链接信息失败,强制终止继续执行 ( ' + getTime() + ' )', end = '')            os._exit(0)    handler.close()    print('\n\n ------------------ ( END ) \033[0;31;40m省份链接\033[0m ( ' + getTime() + ' ) ------------------\n\n\n')

解析省份数据

保存省份数据

这里我只保存成 Json 格式的数据了,如果需要插入到 MySQL 的数据的话,请自行修改,拼装成 Insert into ... 等形式的语句后保存到文件里头即可。

# 保存省份数据信息def saveProvinceData():    print(' ------------------ ( START ) 省份数据 ( ' + getTime() + ' ) ------------------\n')    provinceDataFile = dataPath + provinceFileName    cityLinkFile = linkPath + cityFileName    provinceExistData = []    with open(provinceDataFile, 'r+', encoding = 'utf-8') as provinceDataFileHandler, open(cityLinkFile, 'r', encoding = 'utf-8') as cityLinkFileHandler:        cityLinkData = json.load(cityLinkFileHandler)        if len(provinceDataList) <= 0 and len(cityLinkData) > 0:            for i in cityLinkData:                if i['pcode'] not in provinceExistData:                    provinceExistData.append(i['pcode'])                    provinceDataList.append({                        'code': i['pcode'],                        'name': i['pname']                    })            saveJsonInfo(provinceDataList, provinceDataFileHandler)            print(' ( \033[0;32;40mWONDERFUL\033[0m ) ' + str(len(provinceDataList)) + ' 条省份数据保存成功 ( ' + provinceDataFile + ' )\n')        elif len(provinceDataList) > 0:            saveJsonInfo(provinceDataList, provinceDataFileHandler)            print(' ( \033[0;32;40mWONDERFUL\033[0m ) ' + str(provinceTotalNum) + ' 条省份数据保存成功 ( ' + provinceDataFile + ' )\n')        else:            print(' ( \033[0;31;40mERROR\033[0m ) 省份数据缺失,请检查 ( ' + cityLinkFile + ' )\n')    cityLinkFileHandler.close()    provinceDataFileHandler.close()    print(' ------------------ ( END ) 省份数据 ( ' + getTime() + ' ) ------------------\n\n\n')

保存省份数据

总结

,这个是我自己搭建的 Gogs 平台,代码我就放在这儿了,暂时没上传到 Github 上去。因为接下来的 城镇 / 地区 / 社区等的获取形式与省份信息的获取与保存类似,这里不逐一粘贴代码了,有需要的可以去看看源码,这里只是粘贴了一些核心部分代码。因为总的数据量有点大,我也就将我“抓取”到的数据也一并传到 Gogs 上了,单单社区 / 村落级别的信息,就 33 万多条数据了,再往上一层的镇级别,也有 21 万数据。另外需要注意下最后一个级别(社区 / 村 / 居民委员会)的数据获取,有部分字眼需要替换,有重复的。

标签: #mysql省份