Author:baiyucraft
BLog: baiyucraft’s Home
IDE:PyCharm
上一篇我们对于有道翻译进行了网页的抓取,那我们就想,既然网页内容抓取到了,那是否能用代码来实现有道翻译的功能呢? 答案是显然的!!!
一、urlopen的进一步认识 我们首先对于urlopen进一步的认识
urllib.request.urlopen (url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)
可以看到urlopen的第二个参数是data,data是数据的意思
当我们在url中输入的是网页链接时,并且data有内容时,会向服务器发送数据,并返回接收到数据,有了这个参数,我们就可以实现有道翻译的翻译功能
二、用浏览器的开发者工具查看接口 那又有了一个问题,数据是什么样的形式呢,我们打开有道翻译界面,同样按F12调出开发者工具,我们将选项框调到Network,中文意思就是网络的意思,如下图所示:
然后我们现在在有道翻译的输入框内输入想要翻译的文字,我这里输入了This is my first Python program:
可以发现多出了好多数据,由于现在有道翻译采取的是实时翻译的功能,所以要是输入慢的话就会有好多数据,我们选择XHR类型的数据,然后点击最后一行:
发现第一行的数据叫Request URL,顾名思义,请求链接的意思,这是我们接下来要用到的数据:
拉到最下面,可以发现有个叫Form Data的数据包,第一行的数据叫就是This is my first Python program,使我们想要翻译的文本,这一整个Form Data包也是我们接下来会用到的
三、开始编写我们的程序 有了这个信息,我们可以开始编写代码了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 from urllib import requestif __name__ == '__main__' : request_url = 'http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule' form_data = { 'form' : 'AUTO' , 'to' : 'AUTO' , 'smartresult' : 'dict' , 'client' : 'fanyideskweb' , 'salt' : '15831261181564' , 'sign' : '4bc0cb26b46ed67f51b3992af153d40b' , 'ts' : '1583126118156' , 'bv' : '35242348db4225f3512aa00c2f3e7826' , 'doctype' : 'json' , 'version' : '2.1' , 'keyfrom' : 'fanyi.web' , 'action' : 'FY_BY_REALTlME' } form_data['i' ] = 'This is my first Python program' res = request.urlopen(request_url,form_data) html = res.read().decode('utf-8' ) print (html)
奇怪的是程序居然报错了,位置是在第24行res = request.urlopen(request_url,form_data)
,报错的原因是这个:
TypeError: can’t concat str to bytes
通过分析可以发现 data参数应该是bytes类型的,而我们创建的form_data字典是string类型的,这时候我们就需要用urllib包中的urllib.parse库,并运用其中的函数urlencode()
urllib.parse.urlencode(query, doseq=False, safe=‘’, encoding=None, errors=None, quote_via=quote_plus)
运用urlencode()函数将我们的form_data转换成百分比编码的ASCII文本字符串,然后运用edcode()方法将字符串编码成浏览器可以识别,通过这两个方法继续完善我们的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 from urllib import requestfrom urllib import parse if __name__ == '__main__' : request_url = 'http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule' form_data = { 'form' : 'AUTO' , 'to' : 'AUTO' , 'smartresult' : 'dict' , 'client' : 'fanyideskweb' , 'salt' : '15831261181564' , 'sign' : '4bc0cb26b46ed67f51b3992af153d40b' , 'ts' : '1583126118156' , 'bv' : '35242348db4225f3512aa00c2f3e7826' , 'doctype' : 'json' , 'version' : '2.1' , 'keyfrom' : 'fanyi.web' , 'action' : 'FY_BY_REALTlME' } form_data['i' ] = 'This is my first Python program' data = parse.urlencode(form_data).encode('utf-8' ) res = request.urlopen(request_url,data) html = res.read().decode('utf-8' ) print (html)
程序倒是运行成功了,但是返回的结果是这个:
{“errorCode”:50}
其实原因是因为有道翻译官方设置了反爬虫机智,我们仔细观察请求链接会发现: http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule
的translate
后面有个_o
,当我们把这个去掉后,代码就能成功运行了,运行的结果是:
{“type”:“EN2ZH_CN”,“errorCode”:0,“elapsedTime”:1,“translateResult”:[[{“src”:“Python”,“tgt”:“Python”}]]}
这其实是json格式的数据,我们还需要对这个数据处理一下,用json库的loads()函数对结果进行解码,所以代码改成:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 from urllib import requestfrom urllib import parse import jsonif __name__ == '__main__' : request_url = 'http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule' form_data = { 'form' : 'AUTO' , 'to' : 'AUTO' , 'smartresult' : 'dict' , 'client' : 'fanyideskweb' , 'salt' : '15831261181564' , 'sign' : '4bc0cb26b46ed67f51b3992af153d40b' , 'ts' : '1583126118156' , 'bv' : '35242348db4225f3512aa00c2f3e7826' , 'doctype' : 'json' , 'version' : '2.1' , 'keyfrom' : 'fanyi.web' , 'action' : 'FY_BY_REALTlME' } form_data['i' ] = 'This is my first Python program' data = parse.urlencode(form_data).encode('utf-8' ) res = request.urlopen(request_url,data) html = res.read().decode('utf-8' ) html_js = json.loads(html) print (html_js)
运行结果:
{‘type’: ‘EN2ZH_CN’, ‘errorCode’: 0, ‘elapsedTime’: 1, ‘translateResult’: [[{‘src’: ‘This is my first Python program’, ‘tgt’: ‘这是我第一次Python程序’}]]}
这是python字典的格式,接着我们要提取中间的翻译文本这是我第一次Python程序
,我们一步一步来,先去除键'translateResult'
中的值
1 2 translate = html_js['translateResult' ]
一个[]
表示一个列表,提取列表中的信息
1 2 3 4 translate = html_js['translateResult' ][0 ] translate = html_js['translateResult' ][0 ][0 ]
这又是一个字典,提取键'tgt'
中的值
1 2 translate = html_js['translateResult' ][0 ][0 ]['' tgt]
我们所需要的终于提取出来了,对方法进行封装,并最终交互,最终代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 from urllib import requestfrom urllib import parse import jsondef youdao (t ): request_url = 'http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule' form_data = { 'form' : 'AUTO' , 'to' : 'AUTO' , 'smartresult' : 'dict' , 'client' : 'fanyideskweb' , 'salt' : '15831261181564' , 'sign' : '4bc0cb26b46ed67f51b3992af153d40b' , 'ts' : '1583126118156' , 'bv' : '35242348db4225f3512aa00c2f3e7826' , 'doctype' : 'json' , 'version' : '2.1' , 'keyfrom' : 'fanyi.web' , 'action' : 'FY_BY_REALTlME' } form_data['i' ] = t data = parse.urlencode(form_data).encode('utf-8' ) res = request.urlopen(request_url, data) html = res.read().decode('utf-8' ) html_js = json.loads(html) translate = html_js['translateResult' ][0 ][0 ]['tgt' ] return translateif __name__ == '__main__' : t = input ('请输入想要翻译的内容:' ) translate = youdao(t) print ('翻译的结果是: ' + translate)
我们的python爬虫调用有道翻译的接口并实现翻译功能的程序就完成了!!!