介:本文介绍使用Python,爬取国家统计局网站区划和城乡划分代码数据,并保存为不同的格式。该功能可为电商等行业规范客户邮寄地址的填写提供帮助。
行政区划数据取自国家统计局网站(http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/),数据按行政级别由大到下通过链接和纯html文本嵌套呈现。如河北省:
获取顶级区域(省/直辖市/自治区,不含港澳台)的地址是 http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2021/index.html。其中的“2021”代表数据时间版本。
区划代码格式定义参见“民政部行政区划规则(https://www.mca.gov.cn/article/sj/xzqh/1980/)”。
通过Python分析网页,从顶级区域自动识别各级子区域代码和名称,并保存为不同的数据格式,以供其他业务进一步使用。本Python程序可将爬取后的数据另存为
以河北省为例:文件名中的13是河北省区划代码;文件中ID是自定义的数据主键,2021是数据版本号。
html表格文件,文件名 address_model_13.html
Excel格式文件:文件名 address_model_13.xlsx
sql格式文件:文件名 address_model_13.sql
json格式文件:文件名 address_model_13.json。json格式文件是按行政区域的级联形式,不带ID和版本号字段。
Python需要本版3.5以上,且要安装requests,pandas,BeautifulSoup库
程序可在命令行直接运行:
python AddressUtil.py
参数在程序中设置,分别是
province:顶级区域代码,province = 0时获取顶级区域数据,可用于测试,减少获取数据等待的时间
out_format:输出格式
参数取值见源程序
程序运行时会打印获取的区域进度和异常
出现“request timeout”时说明由于网络问题未获取网页需要重试。本程序设置了三次重试,如三次重试仍未获取,则程序退出,请检查你的网络连接和统计局网站是否有问题。
区划代码数据的使用,引用统计局网站原文——“统计用区划代码和城乡划分代码用于统计工作,需要在其他工作中使用时,请务必结合有关实际情况。”
本文涉及的Python程序和数据样例可从百度网盘下载
https://pan.baidu.com/s/1Jhd_4NPn12WtteOW3IP3AA?pwd=1234 提取码: 1234
特别声明:本人保留源程序版权,源程序可供任何人自由使用(包括商业行为),本人不对使用本程序的后果承担任何责任。使用时请标注或保留原作者名:双鱼菜青虫(账号)。
用Python获取天气预报,想想是件很简单的事情。无非是发送一个HTTP请求,再解析请求返回的结果。当你真的使用Python程序去获取天气预报以后,会发现,有不少坑在等着你。这里简单记录一下我遇到的坑,供大家参考。
这是小编整理的python学习资料,关注,转发,私信小编“01”即可获取拉!
如何获取
使用Python获取天气有两种不同的方法,一种是像平时爬虫一样,获取天气预报网站的HTML页面,再使用XPath或BeautifulSoup解析HTML页面的内容。这是比较传统的爬虫方式。此外,还有另外一种比较合适的方法——通过天气预报网站提供的API。通过API,直接获取结构化的数据,省去了解析HTML的烦恼。
使用API
搜索"天气预报 API"这两个关键字,会有很多相关的内容,例如,这个
https://wwwzhihu.com/question/20575288
答案下就列出了不少提供API访问天气预报的网站。
然而,大部分都已经不可用了。部分可用的需要收费或者需要注册,都比较麻烦。有没有比较省事的方案呢?找来找去,我找到了中国天气网的API。无需注册直接可用,返回json格式的数据,无需使用BeautifulSoup或XPath解析,非常的方便。赞!
例如,可以直接访问下面的地址,在浏览器中查看中国天气网返回的json数据:
http://www.weather.com.cn/data/sk/101020100.html
有了API处理起来就很简单了,直接使用Python世界最知名的requests访问API即可。
安装requests:
pip install requests
检查安装是否成功:
python -c "import requests"
使用ipython测试:
requests库包含一个名为json的方法,当请求的地址返回的是json格式的数据时,直接使用该方法访问即可,无需使用标准库的json库。
解决乱码
如果大家刚才在浏览器中打开了我给的地址,会发现,输出结果是乱码的。如下所示:
我们可以在ipython中,查看数据编码:
我们知道,乱码是因为解码的字符集与编码的字符集不一样,所以才会有乱码。那么,我们怎么知道数据的编码字符集呢?这个时候就靠猜了。众所周知,utf-8因为各种优点(如果大家感兴趣,我可以写一篇字符集编码的文章),是使用最广泛的字符集编码,因此,我们可以尝试使用utf-8进行解码。如下所示:
可以看到,使用utf-8解码以后,可以正确的显示数据。也就是说,中国天气网返回给我们的数据,应该是utf-8格式的。那么,为什么会乱码呢?这可能是中国天气网的工程师水平不行,也可能是故意不想让我们使用,谁知道呢。
我们已经知道了正确的编码,接下来,只要将相应的数据,使用utf-8格式解码即可。requests库本身提供了这样的功能,如下所示:
获取不同城市的天气预报
前面的例子,获取的是上海的天气预报。如果想要使用中国天气网的API,获取其他城市的天气预报呢?中国天气网并没有提供相应的接口,我们只能自己想办法。
在我们测试的URL中,101020100是城市的代码,我们只需要找到其他城市的代码,将101020100替换成相应的代码即可。查找方法是,在中国天气网的首页,搜索城市的名称,地址栏中会显示相应城市的代码。如下所示:
4行Python代码获取天气预报
使用Python获取天气预报的例子中,我们的主要任务在于找到相应的API,解决字符集编码问题。当这些问题解决以后,直接使用requests库获取天气预报即可。下面是获取所在城市天气预报的4行Python代码:
网络时代,我们随时可能要关注的信息之一就是天气,在本文中我们使用HTTP请求来从网站上抓取天气信息的JSON数据,并使用Qt中有关JSON数据处理类来完成对这些数据的解析,并提取天气状态(阴,晴,雨等),最低最高温,风力,感冒指数等信息并显示出来。
JSON是一种编码来自Javascript的对象数据的格式,现已广泛用作Internet上的数据交换格式。PyQt提供了处理JSON数据的支持。
PyQt中的JSON支持包括以下类:
QJsonDocument类提供了一种读取和写入JSON文档的方法。QJsonDocument是包装完整的JSON文档的类,可以从基于UTF-8编码的文本表示形式以及Qt自己的二进制格式读取和写入此文档。使用QJsonDocument. fromJson()将JSON文档从其基于文本的表示形式转换为QJsonDocument. 使用toJson()将其转换回文本。
常用函数:
QJsonParseError类用于在JSON解析期间报告错误。错误类型由枚举量QJsonParseError.ParseError表示:
QJsonParseError常用函数:
JSON是一种存储结构化数据的格式。它具有6种基本数据类型:
代码演示了使用Http请求从网站中下载天气信息,并使用Qt提供的JSON支持,将数据解析提出出来,显示在界面上,在程序中, 省会级一些知名城市可以直接选择,然后获得天气信息,也可以手动输入城市名来查询天气信息。完整代码如下:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import Qt, QJsonDocument, QJsonParseError, QUrl, pyqtSignal
from PyQt5.QtWidgets import (QApplication, QWidget, QLabel, QPushButton, QLineEdit,
QGroupBox,QComboBox, QVBoxLayout, QHBoxLayout, QFormLayout,
QFrame, QPlainTextEdit)
from PyQt5.QtNetwork import QNetworkRequest, QNetworkAccessManager, QNetworkReply
class DemoWeather(QWidget):
getWeather = pyqtSignal(bool)
def __init__(self, parent=None):
super(DemoWeather, self).__init__(parent)
# 设置窗口标题
self.setWindowTitle('实战 Qt for Python: 天气信息查询')
# 设置窗口大小
self.resize(420, 200)
self.initUi()
#保存数据
self.comfortLevel = '' #舒适度(感冒指数)
self.cityName='' #城市名称
self.weather='' #天气类型
self.temperature='' #温度范围
self.wind='' #风
self.nam = QNetworkAccessManager(self)
self.nam.finished.connect(self.replyFinished)
self.getWeather.connect(self.slotGetWeather)
#初始情况,加入北京的天气
self.getWeatherData('北京')
#设置外观界面
def initUi(self):
#采用选择方式查询
cities = ['北京', '天津', '上海', '重庆', '哈尔滨', '长春', '沈阳', '石家庄', '济南', '郑州',
'太原', '西安','呼和浩特', '银川', '兰州', '西宁','乌鲁木齐', '拉萨', '昆明', '成都',
'贵阳','南宁', '广州', '海口', '福州', '南昌', '长沙', '武汉', '合肥', '南京', '杭州',
'台北', '香港', '澳门', '深圳', '厦门', '青岛', '大连']
self.comboBoxCity = QComboBox()
self.comboBoxCity.addItems(cities)
self.comboBoxCity.activated.connect(self.selectCityChanged)
labelCity = QLabel('城市(&C)')
labelCity.setBuddy(self.comboBoxCity)
cityLayout = QFormLayout()
cityLayout.setSpacing(16)
cityLayout.addRow(labelCity, self.comboBoxCity)
#手动输入城市的方式查询
grpBox = QGroupBox('手动查询(&M)')
grpBox.setMaximumWidth(120)
self.editCity = QLineEdit()
#输入完成敲回车键查询
self.editCity.returnPressed.connect(self.slotQueryWeather)
btnQuery = QPushButton('查询')
btnQuery.clicked.connect(self.slotQueryWeather)
manualLayout = QFormLayout()
manualLayout.addRow('请输入城市名称:', self.editCity)
manualLayout.addRow('', btnQuery)
grpBox.setLayout(manualLayout)
#左边的布局
leftLayout = QVBoxLayout()
leftLayout.setSpacing(20)
leftLayout.addLayout(cityLayout)
leftLayout.addWidget(grpBox)
leftLayout.addStretch(1)
#右边信息显示
self.showCity = QLineEdit()
self.showCity.setReadOnly(True)
self.showWeather = QLineEdit()
self.showWeather.setReadOnly(True)
self.showTemperature = QLineEdit()
self.showTemperature.setReadOnly(True)
self.showWind = QLineEdit()
self.showWind.setReadOnly(True)
self.showComfortLevel = QPlainTextEdit()
self.showComfortLevel.setReadOnly(True)
#右边的布局
rightLayout = QFormLayout()
rightLayout.addRow('城市:', self.showCity)
rightLayout.addRow('天气:', self.showWeather)
rightLayout.addRow('温度:', self.showTemperature)
rightLayout.addRow('风力', self.showWind)
rightLayout.addRow('感冒指数:', self.showComfortLevel)
#分隔线
spacerLine = QFrame()
spacerLine.setFrameShape(QFrame.VLine)
mainLayout = QHBoxLayout()
mainLayout.setSpacing(16)
mainLayout.addLayout(leftLayout)
mainLayout.addWidget(spacerLine)
mainLayout.addLayout(rightLayout)
self.setLayout(mainLayout)
def selectCityChanged(self):
cityName = self.comboBoxCity.currentText()
self.getWeatherData(cityName)
def slotQueryWeather(self):
cityName = self.editCity.text()
self.getWeatherData(cityName)
#从网络上获得指定城市的天气数据信息
def getWeatherData(self, cityName):
url = 'http://wthrcdn.etouch.cn/weather_mini?city=%s' % cityName
print(url)
self.nam.get(QNetworkRequest(QUrl(url)))
#接收网络的回复数据
def replyFinished(self, reply):
data = reply.readAll()
#编码转换
#text = bytes.decode(data.data(), encoding='utf8')
#print(text)
self.processReplyData(data)
reply.deleteLater()
#解析接收到的数据
def processReplyData(self, data):
desc = ''
jsonErr = QJsonParseError()
jsonDoc = QJsonDocument.fromJson(data, jsonErr)
if jsonDoc.isNull():
#空对象,返回
return
rootObj = jsonDoc.object()
if 'data' in rootObj:
dataObj = rootObj['data'].toObject()
if 'forecast' in dataObj:
forecastObj = dataObj['forecast']
if forecastObj.isArray():
valArray = forecastObj.toArray()
#只取当天的数据
val = valArray[0].toObject()
self.weather=val['type'].toString() #天气类型
lowTemp=val['low'].toString() #最低温度
highTemp=val['high'].toString() #最高温度
self.temperature=lowTemp[2:] + ' -' + highTemp[2:]
fengxiang = val['fengxiang'].toString()
fengli = val['fengli'].toString()
self.wind = fengxiang + fengli[9:-3]
if 'city' in dataObj:
cityObj = dataObj['city']
if cityObj.isString():
self.cityName = cityObj.toString()
if 'ganmao': #舒适度指数
ganmaoObj = dataObj['ganmao']
if ganmaoObj.isString():
self.comfortLevel = ganmaoObj.toString()
if 'desc' in rootObj: #描述信息
descObj = rootObj['desc']
if descObj.isString():
desc = descObj.toString()
if desc == 'OK':
self.getWeather.emit(True)
else:
self.getWeather.emit(False)
def slotGetWeather(self, isGet):
if isGet:
self.showCity.setText(self.cityName)
self.showWeather.setText(self.weather)
self.showTemperature.setText(self.temperature)
self.showWind.setText(self.wind)
self.showComfortLevel.setPlainText(self.comfortLevel)
else:
self.showCity.setText('没有该城市天气信息')
self.showWeather.setText('')
self.showTemperature.setText('')
self.showWind.setText('')
self.showComfortLevel.setPlainText('')
if __name__ == '__main__':
app = QApplication(sys.argv)
window = DemoWeather()
window.show()
sys.exit(app.exec())
运行结果如下图:
解析JSON数据
前一篇:实战PyQt5: 130-使用HTTP请求下载文件
*请认真填写需求信息,我们会在24小时内与您取得联系。