介:本文介紹使用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小時內與您取得聯系。