python網(wǎng)絡(luò)操作和有道翻譯api破解

python網(wǎng)絡(luò)操作

基本使用方式

import urllib.request as http

response = http.urlopen("http://www.baidu.com")  # 訪問url
html = response.read()  # 讀取返回?cái)?shù)據(jù)
html = html.decode("utf-8")  # 返回?cái)?shù)據(jù)為2進(jìn)制的字符串,需要解碼
print(html)

打印的是百度的html代碼

下載圖片

import urllib.request as http

response = http.urlopen("http://placekitten.com/600/500")  # 訪問這個(gè)地址會(huì)返回一張jpg圖片
img = response.read()  # 讀取返回?cái)?shù)據(jù)
with open('cat.jpg', 'wb') as file:
    file.write(img)

運(yùn)行效果:

運(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對(duì)象
    hl = hashlib.md5()

    # Tips
    # 此處必須聲明encode
    # 否則報(bào)錯(cuò)為: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'  # 語(yǔ)言列表(可設(shè)置為auto)
data['to'] = 'zh-CHS'  # 語(yǔ)言列表(可設(shè)置為auto)
data['appKey'] = '737a1b528a0b1bd3'  # 應(yīng)用申請(qǐng)的key,可在管理控制臺(tái)查看
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')  # 讀取返回?cái)?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è)", "公共財(cái)"],
        "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)良的;愉快的;虔誠(chéng)的", "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í)主要是講在請(qǐng)求體中添加header啦,順便破解)

按照官方文檔請(qǐng)求api獲取翻譯結(jié)果很簡(jiǎn)單,可惜這個(gè)是收費(fèi)的

image

但是我們可以在網(wǎng)頁(yè)上,使用有道云在線翻譯,無限制的免費(fèi)的翻譯語(yǔ)言,下面我們來嘗試破解有道云在線的api接口

首先我們打開瀏覽器,推薦用chrome,打開有道云翻譯的網(wǎng)頁(yè)

image

接著我們輸入要翻譯的文本,比如:fish

打開調(diào)試模式,F12切換到調(diào)試模式,選擇網(wǎng)絡(luò),之后點(diǎn)擊翻譯

image

可以看到有2個(gè)GET請(qǐng)求和1個(gè)POST請(qǐng)求

那么之前的api調(diào)用,我們封裝了data,在python中,如果不傳data,則為GET請(qǐng)求,如果傳入data,就為POST請(qǐng)求,這里我們選擇POST請(qǐng)求

接著選擇正文當(dāng)中的請(qǐng)求正文

image

可以看到,這里的參數(shù),就是我們之前封裝的data,只是多了一些其他額外的參數(shù)

我們繼續(xù)選擇標(biāo)頭,可以看到請(qǐng)求的url

image

那我們仿照之前的做法,試著寫代碼

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')  # 讀取返回?cái)?shù)據(jù)
print(result)

看代碼似乎沒什么問題,但是一運(yùn)行,就報(bào)如下錯(cuò)誤

{"errorCode":50}

我們仔細(xì)回憶下,在之前的標(biāo)頭下面,還有一個(gè)請(qǐng)求標(biāo)頭,其實(shí)就是header,是不是因?yàn)槿鄙賖eader導(dǎo)致返回錯(cuò)誤碼呢,我們嘗試在請(qǐng)求中添加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')  # 讀取返回?cái)?shù)據(jù)
print(result)

這里我們把'Accept-Encoding': 'gzip, deflate'注釋掉了,這句話的意思是本地接收壓縮格式的數(shù)據(jù),服務(wù)器傳過來壓縮格式gzip的文件,而解壓這種gzip文件只能用deflate算法,瀏覽器能夠自動(dòng)解壓,程序卻不能自動(dòng)解壓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
    }
}

臥槽,牛逼啊兄弟,然而事情并沒有這么簡(jiǎn)單,當(dāng)我們把要翻譯的內(nèi)容,fish,改為其他英文,比如want的時(shí)候,一夜回到解放前

{"errorCode":50}

第一次fish的時(shí)候可以,第二次want就不行,那么能夠想到的,就是兩次請(qǐng)求,除了翻譯的文本不同外,data和header的其他參數(shù)有差異,我們?cè)谠诰€翻譯的網(wǎng)頁(yè)上,輸入want,點(diǎn)擊翻譯,再次抓一個(gè)包,和第一次的包,對(duì)比一下,發(fā)現(xiàn)如下不同

image
image

現(xiàn)在看來,錯(cuò)誤碼應(yīng)該就是由于這幾個(gè)參數(shù)導(dǎo)致的了

"salt"我們之前通過查看官方api文檔知道是一個(gè)隨機(jī)數(shù),這里對(duì)數(shù)字比較敏感的話,應(yīng)該可以看出來是時(shí)間戳

"_rltest__cookies"應(yīng)該也不難看出來是一個(gè)時(shí)間戳

關(guān)鍵就是sign,sign我們之前通過官方api文檔知道,它是appKey+翻譯文本+salt+應(yīng)用秘鑰的MD5值

前面3個(gè)我們都有,關(guān)鍵是這個(gè)應(yīng)用秘鑰是啥

而MD5目測(cè)應(yīng)該是卸載javascript中的,所以我們這里查看一下js代碼

打開fanyi.min.js,將代碼用工具格式化一下,因?yàn)槲覀冃枰纒ign是怎么來的,因此我們?nèi)炙阉饕幌?sign"

image
image

看到這里,相信應(yīng)該都知道,sign是怎么來了吧,沒錯(cuò),應(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對(duì)象
    hl = hashlib.md5()

    # Tips
    # 此處必須聲明encode
    # 否則報(bào)錯(cuò)為: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
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容