4行Python程式碼獲取所在城市天氣預報
使用Python獲取天氣預報,想想是件很簡單的事情。無非是傳送一個HTTP請求,再解析請求返回的結果。當你真的使用Python程式去獲取天氣預報以後,會發現,有不少坑在等著你。這裡簡單記錄一下我遇到的坑,供大家參考。
如何獲取
使用Python獲取天氣有兩種不同的方法,一種是像平時爬蟲一樣,獲取天氣預報網站的HTML頁面,再使用XPath或BeautifulSoup解析HTML頁面的內容。這是比較傳統的爬蟲方式。此外,還有另外一種比較合適的方法——通過天氣預報網站提供的API。通過API,直接獲取結構化的資料,省去了解析HTML的煩惱。
Python學習群:556370268,有大牛答疑,有資源共享!是一個非常不錯的交流基地!歡迎喜歡Python的小夥伴!
使用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測試:
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庫。
解決亂碼
如果大家剛才在瀏覽器中打開了我給的地址,會發現,輸出結果是亂碼的。如下所示:

image
我們可以在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替換成相應的程式碼即可。查詢方法是,在中國天氣網的首頁,搜尋城市的名稱,位址列中會顯示相應城市的程式碼。如下所示:

image
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