python網(wǎng)絡(luò)操作
基本使用方式
import urllib.request as http
response = http.urlopen("http://www.baidu.com") # 訪問url
html = response.read() # 讀取返回數(shù)據(jù)
html = html.decode("utf-8") # 返回數(shù)據(jù)為2進(jìn)制的字符串,需要解碼
print(html)
打印的是百度的html代碼
下載圖片
import urllib.request as http
response = http.urlopen("http://placekitten.com/600/500") # 訪問這個地址會返回一張jpg圖片
img = response.read() # 讀取返回數(shù)據(jù)
with open('cat.jpg', 'wb') as file:
file.write(img)
運(yùn)行效果:
實(shí)戰(zhàn)
有道翻譯API調(diào)用
有道云api調(diào)用參考http://ai.youdao.com/docs/doc-trans-api.s#p02
import urllib.request as http
import urllib.parse
import hashlib
import time
# 生成MD5
def md5(str):
# 創(chuàng)建md5對象
hl = hashlib.md5()
# Tips
# 此處必須聲明encode
# 否則報錯為:hl.update(str) Unicode-objects must be encoded before hashing
hl.update(str.encode(encoding='utf-8'))
return hl.hexdigest()
url = "http://openapi.youdao.com/api"
data = {}
data['q'] = "good" # 要翻譯的文本
data['from'] = 'EN' # 語言列表(可設(shè)置為auto)
data['to'] = 'zh-CHS' # 語言列表(可設(shè)置為auto)
data['appKey'] = '737a1b528a0b1bd3' # 應(yīng)用申請的key,可在管理控制臺查看
data['salt'] = '123' # 隨機(jī)數(shù)
data['sign'] = md5(
data['appKey'] + data['q'] + data[
'salt'] + 'A73ACjRHpYSdDBxNKqypvvkhJe80xKMM') # 簽名,appKey+q+salt+應(yīng)用密鑰的MD5值
data = urllib.parse.urlencode(data).encode('utf-8') # python默認(rèn)編碼格式為unicode,這里要轉(zhuǎn)成utf-8
response = http.urlopen(url, data)
result = response.read().decode('utf-8') # 讀取返回數(shù)據(jù)
print(result)
運(yùn)行結(jié)果:
{
"tSpeakUrl": "http://openapi.youdao.com/ttsapi?q=?¥?&langType=zh-CHS&sign=A406F0B74104D2077E00DFA0A64A8A16&salt=1531378824486&voice=4&format=mp3&appKey=737a1b528a0b1bd3",
"web": [{
"value": ["好", "善", "商品"],
"key": "Good"
}, {
"value": ["公共物品", "公益事業(yè)", "公共財"],
"key": "public good"
}, {
"value": ["干的出色", "干得好", "好工作"],
"key": "Good Job"
}],
"query": "good",
"translation": ["好"],
"errorCode": "0",
"dict": {
"url": "yddict://m.youdao.com/dict?le=eng&q=good"
},
"webdict": {
"url": "http://m.youdao.com/dict?le=eng&q=good"
},
"basic": {
"us-phonetic": "ɡ?d",
"phonetic": "g?d",
"uk-phonetic": "g?d",
"uk-speech": "http://openapi.youdao.com/ttsapi?q=good&langType=en&sign=AC9AACC9E2AEB612E1F732799D63770D&salt=1531378824486&voice=5&format=mp3&appKey=737a1b528a0b1bd3",
"explains": ["n. 好處;善行棕孙;慷慨的行為", "adj. 好的凶硅;優(yōu)良的胧洒;愉快的;虔誠的", "adv. 好", "n. (Good)人名医增;(英)古德洼怔;(瑞典)戈德"],
"us-speech": "http://openapi.youdao.com/ttsapi?q=good&langType=en&sign=AC9AACC9E2AEB612E1F732799D63770D&salt=1531378824486&voice=6&format=mp3&appKey=737a1b528a0b1bd3"
},
"l": "EN2zh-CHS",
"speakUrl": "http://openapi.youdao.com/ttsapi?q=good&langType=en&sign=AC9AACC9E2AEB612E1F732799D63770D&salt=1531378824486&voice=4&format=mp3&appKey=737a1b528a0b1bd3"
}
有道云翻譯api破解(其實(shí)主要是講在請求體中添加header啦,順便破解)
按照官方文檔請求api獲取翻譯結(jié)果很簡單,可惜這個是收費(fèi)的
但是我們可以在網(wǎng)頁上,使用有道云在線翻譯,無限制的免費(fèi)的翻譯語言,下面我們來嘗試破解有道云在線的api接口
首先我們打開瀏覽器,推薦用chrome,打開有道云翻譯的網(wǎng)頁
接著我們輸入要翻譯的文本,比如:fish
打開調(diào)試模式,F12切換到調(diào)試模式,選擇網(wǎng)絡(luò),之后點(diǎn)擊翻譯
可以看到有2個GET請求和1個POST請求
那么之前的api調(diào)用,我們封裝了data,在python中,如果不傳data,則為GET請求,如果傳入data,就為POST請求,這里我們選擇POST請求
接著選擇正文當(dāng)中的請求正文
可以看到,這里的參數(shù),就是我們之前封裝的data,只是多了一些其他額外的參數(shù)
我們繼續(xù)選擇標(biāo)頭,可以看到請求的url
那我們仿照之前的做法,試著寫代碼
import urllib.request as http
import urllib.parse
import hashlib
import time
# 生成MD5
def md5(str):
hl = hashlib.md5()
hl.update(str.encode(encoding='utf-8'))
return hl.hexdigest()
url = "http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule"
data = {
'action': 'FY_BY_CLICKBUTTION',
'client': 'fanyideskweb',
'doctype': 'json',
'from': 'AUTO',
'i': 'fish',
'keyfrom': 'fanyi.web',
'salt': '1531383453664',
'sign': '476eada25ccbca5b4fad4d87f1ec80ec',
'smartresult': 'dict',
'to': 'AUTO',
'typoResult': 'false',
'version': '2.1'
}
response = http.urlopen(url, urllib.parse.urlencode(data).encode('utf-8'))
result = response.read().decode('utf-8') # 讀取返回數(shù)據(jù)
print(result)
看代碼似乎沒什么問題,但是一運(yùn)行,就報如下錯誤
{"errorCode":50}
我們仔細(xì)回憶下,在之前的標(biāo)頭下面,還有一個請求標(biāo)頭,其實(shí)就是header,是不是因?yàn)槿鄙賖eader導(dǎo)致返回錯誤碼呢,我們嘗試在請求中添加header試試
import urllib.request as http
import urllib.parse
import hashlib
import time
# 生成MD5
def md5(str):
hl = hashlib.md5()
hl.update(str.encode(encoding='utf-8'))
return hl.hexdigest()
url = "http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule"
data = {
'action': 'FY_BY_CLICKBUTTION',
'client': 'fanyideskweb',
'doctype': 'json',
'from': 'AUTO',
'i': 'fish',
'keyfrom': 'fanyi.web',
'salt': '1531383453664',
'sign': '476eada25ccbca5b4fad4d87f1ec80ec',
'smartresult': 'dict',
'to': 'AUTO',
'typoResult': 'false',
'version': '2.1'
}
headers = {
'Accept': 'application/json, text/javascript, */*; q=0.01',
'Accept-Language': 'zh-CN',
# 'Accept-Encoding': 'gzip, deflate',
'Cache-Control': 'no-cache',
'Connection': 'Keep-Alive',
'Content-Length': '204',
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Cookie': 'OUTFOX_SEARCH_USER_ID_NCOO=500507281.7589852; OUTFOX_SEARCH_USER_ID=-1958201970@10.168.8.76; JSESSIONID=aaaTgHrZGrr3BdPW8snsw; ___rl__test__cookies=1531383453650; fanyi-ad-closed=1; fanyi-ad-id=46607',
'Host': 'fanyi.youdao.com',
'Origin': 'http://fanyi.youdao.com',
'Referer': 'http://fanyi.youdao.com/',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/17.17134',
'X-Requested-With': 'XMLHttpRequest'
}
# 注意header的添加方式
request = http.Request(url, data=urllib.parse.urlencode(data).encode('utf-8'), headers=headers)
response = http.urlopen(request)
result = response.read().decode('utf-8') # 讀取返回數(shù)據(jù)
print(result)
這里我們把'Accept-Encoding': 'gzip, deflate'注釋掉了,這句話的意思是本地接收壓縮格式的數(shù)據(jù),服務(wù)器傳過來壓縮格式gzip的文件行施,而解壓這種gzip文件只能用deflate算法,瀏覽器能夠自動解壓魂那,程序卻不能自動解壓gzip,因此就讓服務(wù)器傳原始文件過來吧蛾号,不用壓縮了
運(yùn)行結(jié)果:
{
"translateResult": [
[{
"tgt": "魚",
"src": "fish"
}]
],
"errorCode": 0,
"type": "en2zh-CHS",
"smartResult": {
"entries": ["", "n. 魚,魚類\r\n", "vt. 釣魚冰寻,捕魚须教;搜尋\r\n", "vi. 捕魚皿渗,釣魚斩芭;用鉤撈取\r\n"],
"type": 1
}
}
臥槽,牛逼啊兄弟,然而事情并沒有這么簡單,當(dāng)我們把要翻譯的內(nèi)容,fish,改為其他英文,比如want的時候,一夜回到解放前
{"errorCode":50}
第一次fish的時候可以,第二次want就不行,那么能夠想到的,就是兩次請求,除了翻譯的文本不同外,data和header的其他參數(shù)有差異,我們在在線翻譯的網(wǎng)頁上,輸入want,點(diǎn)擊翻譯,再次抓一個包,和第一次的包,對比一下,發(fā)現(xiàn)如下不同
現(xiàn)在看來,錯誤碼應(yīng)該就是由于這幾個參數(shù)導(dǎo)致的了
"salt"我們之前通過查看官方api文檔知道是一個隨機(jī)數(shù),這里對數(shù)字比較敏感的話,應(yīng)該可以看出來是時間戳
"_rltest__cookies"應(yīng)該也不難看出來是一個時間戳
關(guān)鍵就是sign,sign我們之前通過官方api文檔知道,它是appKey+翻譯文本+salt+應(yīng)用秘鑰的MD5值
前面3個我們都有,關(guān)鍵是這個應(yīng)用秘鑰是啥
而MD5目測應(yīng)該是卸載javascript中的,所以我們這里查看一下js代碼
打開fanyi.min.js,將代碼用工具格式化一下,因?yàn)槲覀冃枰纒ign是怎么來的,因此我們?nèi)炙阉饕幌?sign"
看到這里,相信應(yīng)該都知道,sign是怎么來了吧,沒錯,應(yīng)用秘鑰就是"ebSeFb%=XZ%T[KZ)c(sy!"
下面我們就可以一起愉快的擼代碼了
完整代碼:
import urllib.request as http
import urllib.parse
import hashlib
import time
# 生成MD5
def md5(str):
# 創(chuàng)建md5對象
hl = hashlib.md5()
# Tips
# 此處必須聲明encode
# 否則報錯為:hl.update(str) Unicode-objects must be encoded before hashing
hl.update(str.encode(encoding='utf-8'))
return hl.hexdigest()
request = http.Request("http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule")
request.headers = {
'Accept': 'application/json, text/javascript, */*; q=0.01',
'Accept-Language': 'zh-CN',
'Cache-Control': 'no-cache',
'Connection': 'Keep-Alive',
'Content-Length': '204',
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Cookie': 'OUTFOX_SEARCH_USER_ID=-1958201970@10.168.8.76; OUTFOX_SEARCH_USER_ID_NCOO=500507281.7589852; JSESSIONID=aaaTgHrZGrr3BdPW8snsw; ___rl__test__cookies=' + str(
int(time.time() * 1000)) + '; fanyi-ad-id=46607; fanyi-ad-closed=1',
'Host': 'fanyi.youdao.com',
'Origin': 'http://fanyi.youdao.com',
'Referer': 'http://fanyi.youdao.com/',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/17.17134',
'X-Requested-With': 'XMLHttpRequest'
}
data = {
'action': 'FY_BY_CLICKBUTTION',
'client': 'fanyideskweb',
'doctype': 'json',
'from': 'AUTO',
'i': 'want',
'keyfrom': 'fanyi.web',
'salt': str(int(time.time() * 1000)),
'smartresult': 'dict',
'to': 'AUTO',
'typoResult': 'false',
'version': '2.1'
}
data['sign'] = md5(data['client'] + data['i'] + data['salt'] + "ebSeFb%=XZ%T[KZ)c(sy!")
request.data = urllib.parse.urlencode(data).encode('utf-8')
response = http.urlopen(request)
print(response.read().decode('utf-8'))
運(yùn)行結(jié)果:
{
"translateResult": [
[{
"tgt": "想要",
"src": "want"
}]
],
"errorCode": 0,
"type": "en2zh-CHS",
"smartResult": {
"entries": ["", "n. 需要;缺乏乐疆;貧困划乖;必需品\r\n", "vt. 需要;希望挤土;應(yīng)該琴庵;缺少\r\n", "vi. 需要;缺少\r\n"],
"type": 1
}
}