寫在前面
待解決
1.請(qǐng)求頭中設(shè)置不壓縮
最近在某博客上看到一篇基于python與阿里云的短信發(fā)送腳本,覺得有意思就試著復(fù)現(xiàn)出來椰棘。
整體思路如下
獲取氣象網(wǎng)API數(shù)據(jù)→urllib包→json數(shù)據(jù)格式更便于操作
↓
阿里云設(shè)置→aliyun_SDK→python版本統(tǒng)一
↓
每日定時(shí)執(zhí)行→通過Linux腳本語言完成
抓取天氣
找了老半天膀斋,找到了不僅顯示實(shí)時(shí)天氣淡溯,還有預(yù)測(cè)功能的穩(wěn)定免費(fèi)的氣象API接口(瘋狂打call中...)兵琳。
由于該API支持json與xml兩種格式勃蜘,利用urllib
包可以輕松獲取對(duì)應(yīng)天氣數(shù)據(jù)硕噩。
# -*- coding:utf-8 -*-
import urllib
import json
city = u'北碚' #待查詢城市
city = urllib.parse.quote(city) #這一句很關(guān)鍵....坑太大
weather_url = 'http://www.sojson.com/open/api/weather/json.shtml?city=%s' %city
#抓取網(wǎng)頁信息
req = urllib.request.urlopen(weather_url)
rs = req.read().decode() #采用utf-8解碼
#獲取當(dāng)天數(shù)據(jù),格式如下
#{"date":"04日星期四","sunrise":"07:50","high":"高溫 7.0℃","low":"低溫 5.0℃",
#"sunset":"18:08","aqi":24.0,"fx":"無持續(xù)風(fēng)向","fl":"<3級(jí)","type":"小雨",
#"notice":"下雨了不要緊缭贡,撐傘擋擋就行"}
weather_info = json.loads(rs)['forecast']
短短幾行代碼完成的工作炉擅,中間碰到的坑不少辉懒。
1.API接口重要性
原始博客提供的API接口已經(jīng)過時(shí),對(duì)應(yīng)數(shù)據(jù)已不再更新谍失,于是就在度娘上找了另一個(gè)相對(duì)比較全面的API耗帕。但是在執(zhí)行到倒數(shù)第二步時(shí),解碼失敗袱贮,錯(cuò)誤代碼
'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte
百度一圈發(fā)現(xiàn)仿便,在提交到服務(wù)器的request header中有Accept Encoding : gzip, deflate
這一選項(xiàng),這條信息代表本地可以接收壓縮格式的數(shù)據(jù)攒巍,而服務(wù)器在處理時(shí)就將大文件壓縮再發(fā)回客戶端嗽仪。即,本地接收的不是完整的json格式柒莉,而是壓縮后的gzip格式闻坚,這一點(diǎn)可以通過request.getheaders
查詢響應(yīng)頭信息得到。
然而如何處理請(qǐng)求頭兢孝,讓它不接受壓縮格式窿凤,一直沒弄明白。
最終跨蟹,通過查找另一個(gè)比較合適的API繞過了這個(gè)問題雳殊。
2.url漢字編碼
該url輸入的城市名通過漢字輸入。然而窗轩,都知道漢字是不能作為url輸入的夯秃,需要對(duì)其進(jìn)行編碼。
在原API文檔中作者采用utf-8編碼(其實(shí)是基于url的utf-8編碼)痢艺,于是就將漢字轉(zhuǎn)碼為utf-8后再附上url地址仓洼,出現(xiàn)訪問失敗。
提取對(duì)應(yīng)漢字編碼顯示如下
漢字:北碚
utf-8:\xe5\x8c\x97\xe7\xa2\x9a
url : %e5%8c%97%e7%a2%9a
可以發(fā)現(xiàn)堤舒,url將utf-8中的\x
替換為%色建,這是因?yàn)閡rl中不允許出現(xiàn)諸如\
,這樣的字符。更加詳細(xì)的url轉(zhuǎn)碼文檔參考阮一峰的博客
博客簡述
1.url中漢字若為路徑舌缤,則為對(duì)應(yīng)utf-8編碼相關(guān)位置替換為%
2.url漢字若為搜索關(guān)鍵字箕戳,則用的是操作系統(tǒng)的默認(rèn)編碼
3.GET和POST方法的編碼,用的是網(wǎng)頁的編碼
4.其余過于復(fù)雜友驮,略過
3. python2.7 vs python3
由于python版本不向下兼容漂羊,2.7版本python語法與3以后語法有很大差別⌒读簦考慮后續(xù)阿里云API采用2.6版本走越,因而需要對(duì)這里urllib模塊進(jìn)行轉(zhuǎn)換為2.6格式。
由于全文采用的只有urllib
模塊耻瑟,因而只需小規(guī)模修改即可旨指。
urllib在python2與python3區(qū)別
修改后代碼如下
# -*- coding:utf-8 -*-
__author__ = 'lumo_wang'
import urllib
import urllib2
import json
city = '北碚'
city_encode = urllib.quote(city)
weather_url = 'http://www.sojson.com/open/api/weather/json.shtml?city=%s' %city_encode
request = urllib2.urlopen(weather_url)
rs = request.read().decode('utf-8')
weather_info = json.loads(rs)['data']['forecast'][0]
#數(shù)據(jù)提取赏酥,主要用于刪除溫度中的漢字
def s2t(string):
switch=False
temp=''
for s in string:
if switch==True:
temp+=s
if s==u' ':
switch=True
return temp
#信息分解
time = weather_info['date'] #日期——04日星期四
temp_l = weather_info['low'] #低溫——低溫 5.0℃
low=s2t(temp_l)
temp_h = weather_info['high'] #高溫——高溫 7.0℃
high-s2t(temp_h)
aqi = weather_info['aqi'] #aqi指數(shù)——23.0
weather= weather_info['type'] #天氣——小雨
阿里云SDK配置
這一段...由于實(shí)驗(yàn)室主機(jī)最近沒網(wǎng),等弄好了整個(gè)代碼跑通了再寫谆构。