
中英互譯
python的urllib可謂http操作的神器,可以模仿瀏覽器的行為提交請求并收到返回的數(shù)據(jù)。筆者在此利用urllib向百度翻譯發(fā)送翻譯請求并獲取翻譯結(jié)果,演示一下該庫的簡單用法,小腳本封裝后可以在命令行下運行,非常適用于linux。
功能分析
- 輸入中文或英文,返回翻譯結(jié)果。
代碼實現(xiàn)
- urllib發(fā)送請求的方法
#!/usr/bin/env python3
from urllib import request, parse
import json
import sys
# 新建請求
requ = request.Request('http://...') # 輸入請求的目標網(wǎng)址
# 以post方式提交數(shù)據(jù)需要對數(shù)據(jù)轉(zhuǎn)碼打包
post_data = parse.urlencode({
"key": "val",
# ...
})
# 添加請求頭request-header
requ.add_header(key, val) # 請求頭可以從瀏覽器控制臺獲取,可以多次調(diào)用
# 發(fā)送請求獲取響應(yīng)數(shù)據(jù)
with request.urlopen(requ, post_data.encode('utf-8')) as resp
resp_data = resp.read() # 字節(jié)數(shù)據(jù),可根據(jù)需要解碼為字符
以上就是urllib發(fā)送請求并獲取相應(yīng)數(shù)據(jù)的一般方法,下面根據(jù)上面的模板向百度翻譯發(fā)送翻譯請求。
- 翻譯小程序
#!/usr/bin/env python3
from urllib import request, parse
import json
import sys
def show_help():
print('help...')
def main():
if len(sys.argv) < 2:
show_help()
return
words = sys.argv[1]
# post數(shù)據(jù)結(jié)構(gòu),query為待查詢詞匯
post_data = parse.urlencode({
"from":"zh",
"to":"en",
"query":words,
# "query":"鍵盤",
"transtype":"translang",
"simple_means_flag":"3"
})
requ = request.Request('http://fanyi.baidu.com/v2transapi')
requ.add_header('Host', 'fanyi.baidu.com')
requ.add_header('User-Agent', 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) \
Gecko/20100101 Firefox/50.0')
requ.add_header('Accept', '*/*')
requ.add_header('Accept-Language', 'en-US,en;q=0.5')
requ.add_header('Accept-Encoding', 'en-US,en;q=0.5')
requ.add_header('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8')
requ.add_header('X-Requested-With', 'XMLHttpRequest')
requ.add_header('Referer', r'http://fanyi.baidu.com/translate?aldtype=16047&query=\
%E5%B8%AE%E5%8A%A9&keyfrom=baidu&smartresult=dict&lang=auto2zh')
requ.add_header('Content-Length', '78')
requ.add_header('Cookie', r'BAIDUID=F49EF7F92D1F9D27EBC7CFB34A5EB604:FG=1; BIDUPSID\
=EB895CEBA4E3BAD19DC355A2ED379DED; PSTM=1481521457; H_PS_PSSID=21764_1456_21085\
_17001_21554_20928; PSINO=1; locale=zh; Hm_lvt_64ecd82404c51e03dc91cb9e8c025574\
=1481991435,1481991979; Hm_lpvt_64ecd82404c51e03dc91cb9e8c025574=1481991979; MA\
NUBANNER=1; from_lang_often=%5B%7B%22value%22%3A%22zh%22%2C%22text%22%3A%22%u4E\
2D%u6587%22%7D%2C%7B%22value%22%3A%22en%22%2C%22text%22%3A%22%u82F1%u8BED%22%7D\
%5D; to_lang_often=%5B%7B%22value%22%3A%22en%22%2C%22text%22%3A%22%u82F1%u8BED%\
22%7D%2C%7B%22value%22%3A%22zh%22%2C%22text%22%3A%22%u4E2D%u6587%22%7D%5D; REAL\
TIME_TRANS_SWITCH=1; FANYI_WORD_SWITCH=1; sideAdClose=17152')
requ.add_header('Connection', 'keep-alive')
resp = request.urlopen(requ, post_data.encode('utf-8'))
print(json.loads(resp.read().decode('utf-8')).get('liju_result').get('tag'))
if __name__ == "__main__":
main()
此處請求頭來源于谷歌瀏覽器的控制臺,并不是所有的都是必須的,讀者可自行測試,另外,也可以寫一個函數(shù)來直接對請求頭文本進行自動分割,不需要手動分割。
附錄
1. 請求頭獲取方法
從菜單打開開發(fā)者工具(或者直接F12打開)
打開控制臺
打開Network選項
打開Network
嘗試翻譯,查看請求頭和數(shù)據(jù)格式
查看請求頭
查看響應(yīng)數(shù)據(jù)格式
查看相應(yīng)數(shù)據(jù)結(jié)構(gòu)
利用json模塊可以解析json數(shù)據(jù)。
2. 請求頭文本自動分割方法
def parse_to_array(data_text):
"""Parse header text to tuple array."""
lines = data_text.splitlines()
data_array = []
for l in lines:
data_array.append(tuple(l.split(':',1)))
return data_array
def add_request_headers(reqs, headers):
"""Add request header according of headers text."""
dict_data = parse_to_array(headers)
for k, v in dict_data:
reqs.add_header(k, v)
# 用法展示
headers = """
Accept: */*
...
"""
add_request_headers(reqs, headers)
總結(jié)
利用該方法可以滿足一般的爬取需求,筆者還實現(xiàn)過校園網(wǎng)wifi網(wǎng)頁認證的便捷登陸以及校園網(wǎng)流量監(jiān)控系統(tǒng),后者還需要結(jié)合郵件發(fā)送模塊實現(xiàn)定期自動發(fā)送郵件提醒,有時間寫出來交流交流。



