今天給大家?guī)?lái)的Python實(shí)戰(zhàn)項(xiàng)目是四行Python代碼獲取所在城市的天氣預(yù)報(bào),我們隱隱聽(tīng)到唏噓聲枉圃,不信四行Python代碼可以獲取是嗎?那我們一起來(lái)看看:
使用Python獲取天氣預(yù)報(bào)功茴,想想是件很簡(jiǎn)單的事情庐冯。無(wú)非是發(fā)送一個(gè)HTTP請(qǐng)求孽亲,再解析請(qǐng)求返回的結(jié)果。當(dāng)你真的使用Python程序去獲取天氣預(yù)報(bào)以后展父,會(huì)發(fā)現(xiàn)返劲,有不少坑在等著你。這里簡(jiǎn)單記錄一下我遇到的坑栖茉,供大家參考篮绿。
如何獲取
使用Python獲取天氣有兩種不同的方法,一種是像平時(shí)爬蟲(chóng)一樣吕漂,獲取天氣預(yù)報(bào)網(wǎng)站的HTML頁(yè)面亲配,再使用XPath或BeautifulSoup解析HTML頁(yè)面的內(nèi)容。這是比較傳統(tǒng)的爬蟲(chóng)方式惶凝。此外吼虎,還有另外一種比較合適的方法——通過(guò)天氣預(yù)報(bào)網(wǎng)站提供的API。通過(guò)API苍鲜,直接獲取結(jié)構(gòu)化的數(shù)據(jù)思灰,省去了解析HTML的煩惱。
使用API
搜索”天氣預(yù)報(bào) API”這兩個(gè)關(guān)鍵字混滔,會(huì)有很多相關(guān)的內(nèi)容洒疚,例如,這個(gè)
https:/
python -c "import requests"
/wwwzhihu.com/question/20575288
答案下就列出了不少提供API訪問(wèn)天氣預(yù)報(bào)的網(wǎng)站坯屿。
然而油湖,大部分都已經(jīng)不可用了。部分可用的需要收費(fèi)或者需要注冊(cè)领跛,都比較麻煩乏德。有沒(méi)有比較省事的方案呢?找來(lái)找去,我找到了中國(guó)天氣網(wǎng)的API隔节。無(wú)需注冊(cè)直接可用鹅经,返回json格式的數(shù)據(jù)寂呛,無(wú)需使用BeautifulSoup或XPath解析,非常的方便瘾晃。贊!
例如贷痪,可以直接訪問(wèn)下面的地址,在瀏覽器中查看中國(guó)天氣網(wǎng)返回的json數(shù)據(jù):
http://www.weather.com.cn/data/sk/101020100.html
有了API處理起來(lái)就很簡(jiǎn)單了蹦误,直接使用Python世界最知名的requests訪問(wèn)API即可劫拢。
安裝requests:
pip install requests
檢查安裝是否成功:
python -c “import requests”
使用ipython測(cè)試:
In [1]: import requests
In [2]: r = requests.get('http://www.weather.com.cn/data/sk/101020100.html')
In [3]: r.status_code
Out[3]: 200
In [4]: r.content
Out[4]: '{"weatherinfo":{"city":"????μ·","cityid":"101020100","temp":"15","WD":"???é£?","WS":"1?o§","SD":"50%","WSE":"1","time":"17:08","isRadar":"1","Radar":"JC_RADAR_AZ9210_JB","njd":"????? ?????μ","qy":"1020","rain":"0"}}'
In [5]: r.json()
Out[5]: {u'weatherinfo': {u'Radar': u'JC_RADAR_AZ9210_JB',
? u'SD': u'50%',
? u'WD': u'???�',
? u'WS': u'1?o§',
? u'WSE': u'1',
? u'city': u'????μ·',
? u'cityid': u'101020100',
? u'isRadar': u'1',
? u'njd': u'????? ?????μ',
? u'qy': u'1020',
? u'rain': u'0',
? u'temp': u'15',
? u'time': u'17:08'}}
requests庫(kù)包含一個(gè)名為json的方法,當(dāng)請(qǐng)求的地址返回的是json格式的數(shù)據(jù)時(shí)强胰,直接使用該方法訪問(wèn)即可舱沧,無(wú)需使用標(biāo)準(zhǔn)庫(kù)的json庫(kù)。
解決亂碼
如果大家剛才在瀏覽器中打開(kāi)了我給的地址偶洋,會(huì)發(fā)現(xiàn)熟吏,輸出結(jié)果是亂碼的。如下所示:
我們可以在ipython中玄窝,查看數(shù)據(jù)編碼:
In [6]: r.encoding
Out[6]: 'ISO-8859-1'
我們知道牵寺,亂碼是因?yàn)榻獯a的字符集與編碼的字符集不一樣,所以才會(huì)有亂碼恩脂。那么帽氓,我們?cè)趺粗罃?shù)據(jù)的編碼字符集呢?這個(gè)時(shí)候就靠猜了。眾所周知俩块,utf-8因?yàn)楦鞣N優(yōu)點(diǎn)(如果大家感興趣黎休,我可以寫(xiě)一篇字符集編碼的文章),是使用最廣泛的字符集編碼玉凯,因此势腮,我們可以嘗試使用utf-8進(jìn)行解碼。如下所示:
In [7]: r.json()['weatherinfo']['city']
Out[7]: u'????μ·'
In [8]: '????μ·'.decode('utf-8')
Out[8]: u'上海'
In [9]: print '????μ·'.decode('utf-8')
上海
可以看到壮啊,使用utf-8解碼以后嫉鲸,可以正確的顯示數(shù)據(jù)。也就是說(shuō)歹啼,中國(guó)天氣網(wǎng)返回給我們的數(shù)據(jù)玄渗,應(yīng)該是utf-8格式的。那么狸眼,為什么會(huì)亂碼呢?這可能是中國(guó)天氣網(wǎng)的工程師水平不行藤树,也可能是故意不想讓我們使用,誰(shuí)知道呢拓萌。
我們已經(jīng)知道了正確的編碼岁钓,接下來(lái),只要將相應(yīng)的數(shù)據(jù),使用utf-8格式解碼即可屡限。requests庫(kù)本身提供了這樣的功能品嚣,如下所示:
In [10]: r.encoding = 'utf-8'
In [11]: print r.json()['weatherinfo']['city']
上海
獲取不同城市的天氣預(yù)報(bào)
前面的例子,獲取的是上海的天氣預(yù)報(bào)钧大。如果想要使用中國(guó)天氣網(wǎng)的API翰撑,獲取其他城市的天氣預(yù)報(bào)呢?中國(guó)天氣網(wǎng)并沒(méi)有提供相應(yīng)的接口,我們只能自己想辦法啊央。
在我們測(cè)試的URL中眶诈,101020100是城市的代碼,我們只需要找到其他城市的代碼瓜饥,將101020100替換成相應(yīng)的代碼即可逝撬。查找方法是,在中國(guó)天氣網(wǎng)的首頁(yè)乓土,搜索城市的名稱宪潮,地址欄中會(huì)顯示相應(yīng)城市的代碼。如下所示:
4 行Python代碼獲取天氣預(yù)報(bào)
使用Python獲取天氣預(yù)報(bào)的例子中帐我,我們的主要任務(wù)在于找到相應(yīng)的API坎炼,解決字符集編碼問(wèn)題。當(dāng)這些問(wèn)題解決以后拦键,直接使用requests庫(kù)獲取天氣預(yù)報(bào)即可。下面是獲取所在城市天氣預(yù)報(bào)的4行Python代碼:
In [1]: import requests
In [2]: r = requests.get('http://www.weather.com.cn/data/sk/101020100.html')
In [3]: r.encoding = 'utf-8'
In [4]: print r.json()['weatherinfo']['city'], r.json()['weatherinfo']['WD'], r.json()['weatherinfo']['temp']
上海 東風(fēng) 15
感謝您的閱讀檩淋,以上就是我們用四行代碼獲取的上海的天氣預(yù)報(bào)芬为,你現(xiàn)在相信了嗎?還不趕緊套用一下,看看你那的天氣怎么樣蟀悦!