標籤:

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

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

如何獲取

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

使用API

搜索"天氣預報 API"這兩個關鍵字,會有很多相關的內容,例如,這個(zhihu.com/question/2057)答案下就列出了不少提供API訪問天氣預報的網站。

然而,大部分都已經不可用了。部分可用的需要收費或者需要註冊,都比較麻煩。有沒有比較省事的方案呢?找來找去,我找到了中國天氣網的API。無需註冊直接可用,返回json格式的數據,無需使用BeautifulSoup或XPath解析,非常的方便。贊!

例如,可以直接訪問下面的地址,在瀏覽器中查看中國天氣網返回的json數據:

weather.com.cn/data/sk/

有了API處理起來就很簡單了,直接使用Python世界最知名的requests訪問API即可。

安裝requests:

pip install requestsn

檢查安裝是否成功:

python -c "import requests"n

使用ipython測試:

In [1]: import requestsnnIn [2]: r = requests.get(http://www.weather.com.cn/data/sk/101020100.html)nnIn [3]: r.status_codenOut[3]: 200nnIn [4]: r.contentnOut[4]: {"weatherinfo":{"city":"xe4xb8x8axe6xb5xb7","cityid":"101020100","temp":"15","WD":"xe4xb8x9cxe9xa3x8e","WS":"1xe7xbaxa7","SD":"50%","WSE":"1","time":"17:08","isRadar":"1","Radar":"JC_RADAR_AZ9210_JB","njd":"xe6x9ax82xe6x97xa0xe5xaex9exe5x86xb5","qy":"1020","rain":"0"}}nnIn [5]: r.json()nOut[5]: n{uweatherinfo: {uRadar: uJC_RADAR_AZ9210_JB,n uSD: u50%,n uWD: uxe4xb8x9cxe9xa3x8e,n uWS: u1xe7xbaxa7,n uWSE: u1,n ucity: uxe4xb8x8axe6xb5xb7,n ucityid: u101020100,n uisRadar: u1,n unjd: uxe6x9ax82xe6x97xa0xe5xaex9exe5x86xb5,n uqy: u1020,n urain: u0,n utemp: u15,n utime: u17:08}}n

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

解決亂碼

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

我們可以在ipython中,查看數據編碼:

In [6]: r.encodingnOut[6]: ISO-8859-1n

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

In [7]: r.json()[weatherinfo][city]nOut[7]: uxe4xb8x8axe6xb5xb7nnIn [8]: xe4xb8x8axe6xb5xb7.decode(utf-8)nOut[8]: u上海nnIn [9]: print xe4xb8x8axe6xb5xb7.decode(utf-8)nn上海n

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

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

In [10]: r.encoding = utf-8nnIn [11]: print r.json()[weatherinfo][city]nn上海n

獲取不同城市的天氣預報

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

在我們測試的URL中(weather.com.cn/data/sk/),101020100是城市的代碼,我們只需要找到其他城市的代碼,將101020100替換成相應的代碼即可。查找方法是,在中國天氣網的首頁,搜索城市的名稱,地址欄中會顯示相應城市的代碼。如下所示:

4行Python代碼獲取天氣預報

使用Python獲取天氣預報的例子中,我們的主要任務在於找到相應的API,解決字符集編碼問題。當這些問題解決以後,直接使用requests庫獲取天氣預報即可。下面是獲取所在城市天氣預報的4行Python代碼:

In [1]: import requestsnnIn [2]: r = requests.get(http://www.weather.com.cn/data/sk/101020100.html)nnIn [3]: r.encoding = utf-8nnIn [4]: print r.json()[weatherinfo][city], r.json()[weatherinfo][WD], r.json()[weatherinfo][temp]nn上海 東風 15n

歡迎加入MySQL+Python+大數據+NoSQL技術交流QQ群(群號:306706593)。


推薦閱讀:

【爬蟲】解決封IP問題:1.利用ADSL伺服器
對豆瓣《戰狼2》87767 條短評做詞雲
爬取Ajax動態載入和翻頁時url不變的網頁
【Python爬蟲實戰】——爬取今日頭條美女圖片
爬蟲軟體|軟體的簡單使用(二)

TAG:Python | 爬虫 |