歡迎光臨
每天分享高質量文章

4 行 Python 程式碼獲取所在城市天氣預報

(點選上方公眾號,可快速關註一起學Python)

作者:賴明星

連結:https://zhuanlan.zhihu.com/p/26369491

使用Python獲取天氣預報,想想是件很簡單的事情。無非是傳送一個HTTP請求,再解析請求傳回的結果。當你真的使用Python程式去獲取天氣預報以後,會發現,有不少坑在等著你。這裡簡單記錄一下我遇到的坑,供大家參考。

如何獲取

使用Python獲取天氣有兩種不同的方法,一種是像平時爬蟲一樣,獲取天氣預報網站的HTML頁面,再使用XPath或BeautifulSoup解析HTML頁面的內容。這是比較傳統的爬蟲方式。此外,還有另外一種比較合適的方法——透過天氣預報網站提供的API。透過API,直接獲取結構化的資料,省去瞭解析HTML的煩惱。

使用API

搜尋”天氣預報 API”這兩個關鍵字,會有很多相關的內容,例如,這個

zhihu.com/question/2057

答案下就列出了不少提供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測試:

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":"\xe4\xb8\x8a\xe6\xb5\xb7","cityid":"101020100","temp":"15","WD":"\xe4\xb8\x9c\xe9\xa3\x8e","WS":"1\xe7\xba\xa7","SD":"50%","WSE":"1","time":"17:08","isRadar":"1","Radar":"JC_RADAR_AZ9210_JB","njd":"\xe6\x9a\x82\xe6\x97\xa0\xe5\xae\x9e\xe5\x86\xb5","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'\xe4\xb8\x9c\xe9\xa3\x8e',
 u'WS': u'1\xe7\xba\xa7',
 u'WSE': u'1',
 u'city': u'\xe4\xb8\x8a\xe6\xb5\xb7',
 u'cityid': u'101020100',
 u'isRadar': u'1',
 u'njd': u'\xe6\x9a\x82\xe6\x97\xa0\xe5\xae\x9e\xe5\x86\xb5',
 u'qy': u'1020',
 u'rain': u'0',
 u'temp': u'15',
 u'time': u'17:08'}}

requests庫包含一個名為json的方法,當請求的地址傳回的是json格式的資料時,直接使用該方法訪問即可,無需使用標準庫的json庫。

解決亂碼

如果大家剛才在瀏覽器中開啟了我給的地址,會發現,輸出結果是亂碼的。如下所示:

我們可以在ipython中,檢視資料編碼:

In [6]: r.encoding
Out[6]: 'ISO-8859-1'

我們知道,亂碼是因為解碼的字符集與編碼的字符集不一樣,所以才會有亂碼。那麼,我們怎麼知道資料的編碼字符集呢?這個時候就靠猜了。眾所周知,utf-8因為各種優點(如果大家感興趣,我可以寫一篇字符集編碼的文章),是使用最廣泛的字符集編碼,因此,我們可以嘗試使用utf-8進行解碼。如下所示:

In [7]: r.json()['weatherinfo']['city']
Out[7]: u'\xe4\xb8\x8a\xe6\xb5\xb7'

In [8]: '\xe4\xb8\x8a\xe6\xb5\xb7'.decode('utf-8')
Out[8]: u'\u4e0a\u6d77'

In [9]: print '\xe4\xb8\x8a\xe6\xb5\xb7'.decode('utf-8')

上海

可以看到,使用utf-8解碼以後,可以正確的顯示資料。也就是說,中國天氣網傳回給我們的資料,應該是utf-8格式的。那麼,為什麼會亂碼呢?這可能是中國天氣網的工程師水平不行,也可能是故意不想讓我們使用,誰知道呢。

我們已經知道了正確的編碼,接下來,只要將相應的資料,使用utf-8格式解碼即可。requests庫本身提供了這樣的功能,如下所示:

In [10]: r.encoding = 'utf-8'
In [11]: print r.json()['weatherinfo']['city']

上海

獲取不同城市的天氣預報

前面的例子,獲取的是上海的天氣預報。如果想要使用中國天氣網的API,獲取其他城市的天氣預報呢?中國天氣網並沒有提供相應的介面,我們只能自己想辦法。

在我們測試的URL中,101020100是城市的程式碼,我們只需要找到其他城市的程式碼,將101020100替換成相應的程式碼即可。查詢方法是,在中國天氣網的首頁,搜尋城市的名稱,位址列中會顯示相應城市的程式碼。如下所示:

4行Python程式碼獲取天氣預報

使用Python獲取天氣預報的例子中,我們的主要任務在於找到相應的API,解決字符集編碼問題。當這些問題解決以後,直接使用requests庫獲取天氣預報即可。下麵是獲取所在城市天氣預報的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']

上海 東風 15

    贊(0)

    分享創造快樂