个人博客:苏三有春的博客
系类往期文章:
PyQt5实战——多脚本集合包,前言与环境配置(一)
PyQt5实战——多脚本集合包,UI以及工程布局(二)
PyQt5实战——多脚本集合包,程序入口QMainWindow(三)
PyQt5实战——操作台打印重定向,主界面以及stacklayout使用(四)
PyQt5实战——UTF-8编码器UI页面设计以及按钮连接(五)
PyQt5实战——UTF-8编码器功能的实现(六)
PyQt5实战——翻译器的UI页面设计以及代码实现(七)
前言
本文虽然被归类于PyQt开发实战,但实际上并没有关于PyQt的相关知识,这篇文章着重基于上篇文章,讲述笔者在开发翻译器时如何做爬取微软翻译网站时的分析,如何获取到网站所需要的信息。这其中也是夹杂了许多笔者个人的猜想与运气才碰出来的,笔者对爬虫也没有做更深的学习,只有一些粗浅的理解,并结合这个项目一点一点摸出来的,可能有更专业的工具与更成体系的知识架构,笔者也要去学习,希望这篇文章对读者能起到一些帮助和启发。
本文从笔者第一次爬取开始讲起,第一次失败了,总结了失败的经验,第二次才爬取成功。
第一次爬取微软翻译
分析
在笔者进行爬虫的时候,首先先打开了浏览器自带的开发者工具查看网络数据,看看在翻译时客户端与服务器之间做了哪些交流
在排查的过程中,发现有一个名称叫做ttranslate...
的包引起了笔者的注意,点进去发现这其中确实携带了笔者要翻译的信息
从上图中可以看到,包的负载中的表单数据中有一项Text
,携带的数据刚好是我们输入的翻译内容你好
。
打开预览
可以看到更详细的信息
在这里可以发现:
- 这里有我们翻译之前的语种,即:
zh-Hans
,简体中文 - 翻译后的文本,保存在一个名为
translations
的数据中,text
:Hello
,这个数据就是我们要获取的数据,其实这就是对于翻译请求的响应,打开响应界面也是这一串信息
响应界面如下:
所以,本质上,笔者就是想要获得对于这个请求的响应,因此笔者的方法是模仿这个包的请求,读取它的响应,从而获得对应的翻译数据。
实践
因此根据爬虫的流程,笔者先获取了ttranslate
的请求URL,即:
https://cn.bing.com/ttranslatev3?isVertical=1&&IG=94BF74DDDBA34ECB8B2CFB8D7960E4F9&IID=translator.5025
再获取了请求标头中的User-Agent
,即:
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0
如下图所示:
获取URL是为了获取请求的目的地,获取User-Agent是为了让服务器认为我们是一个人,而不是脚本在自动操作(虽然真的是一个脚本),现在这两者已经获取,我们这段信息就有了身份。(虽然请求标头中还有许多其它的信息,但笔者也没搞懂有什么作用,索性也就没管)
接下来这既然是一个请求,那么我们就需要携带需要请求的消息,消息的格式是什么呢?在负载中可以找到,负载就是请求的内容,如下图所示:
显而易见的是,表单数据中携带了我们待翻译内容的语种,翻译结果的语种,以及翻译的数据。我们需要将这些信息放进我们的请求中。
信息收集完毕,开始编写代码(下面展示代码主题,读者需要注意这其中还调用了第三方关于爬虫的库,如报错,请pip install 响应的第三方库)
url = "https://cn.bing.com/ttranslatev3?isVertical=1&&IG=94BF74DDDBA34ECB8B2CFB8D7960E4F9&IID=translator.5025"
header = {"user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36 Edg/129.0.0.0"}
data = {"fromLang":"zh-Hans","to":"en","text":text}
data = urllib.parse.urlencode(data).encode("utf-8")
req = urllib.request.Request(url, data, headers=header)
response = urllib.request.urlopen(req)
html = response.read().decode("utf-8")
target = json.loads(html)
print(target[0]['translations'][0]['text'])
以下,我们来逐行分析代码:
- 将刚刚得到的URL存放起来
- 将
user-agent
也存放起来,存放在header
字典中 - 将我们请求的数据:翻译前的语种,翻译后的语种,文本也存放起来,存放在
data
字典中 - 将
data
进行utf-8
加密,转换成响应的url请求格式 - 使用
Request
方法发送请求,参数为url
,data
,header
- 使用
urlopen
方法获取响应 - 将响应解码
- 将JSON格式的字符串解析成python对象,比如字典,列表等
- 获取这个target中关于
translation
列表下的字典的text
对应的值
总结
以上,是笔者的第一次爬虫,一开始爬取的时候使用正常,可以正常的使用,但没过多久,翻译器无法使用,无故闪退,笔者开始debug,发现已经无法通过这个url发送请求了。
笔者开始整理,经过多次请求尝试和实验,发现url存在一些端倪:
https://cn.bing.com/ttranslatev3?isVertical=1&&IG=94BF74DDDBA34ECB8B2CFB8D7960E4F9&IID=translator.5025
我们再来看一下这个URL,可以发现,这URL本身就携带了一些信息,IG
与IID
,这两个数据在每次会话结束后,都会发生变化,也就是说,当一个会话结束后,笔者所记录的IG
与IID
就失效了,无法访问,因此,这一次爬虫并不成功,还需要继续改进,获取每次访问微软翻译时的IG
和IID
数据。
结语
总的来说,本文只是笔者在爬虫方向上的一次探索与学习,这是一次失败的尝试,不过可以看出,笔者在学习上的思路,笔者在学习时,喜欢在实践中发现问题并解决问题,因为理论与实践总是存在一定的差距,现实世界总是复杂且多变的。在实践中,你总会发现一些与理论有偏差或者相悖的地方,让你陷入迷茫,但是在实践中,你不会没有一点头绪,相反,在实践中,你有太多太多的方向去验证问题的本质,有时候往往是方向太多,你无法确定哪条路才能通向正确,你害怕做了无用功,害怕走错了方向,因此迟迟不敢动手,才导致了自己的踌躇不前。在现实世界中抽丝剥茧,也是一种学习,虽然笔者在这里也走错了路,离成功还有一段距离,但是走到这里,让笔者学会了如何看网络包,分析请求和响应,学会调用request库,以及最重要的找到了正确的道路,即:接下来,我们要想办法找到每一次IG
和IID
这两个数据如何变,在哪里变,如何获取到那个存放这两个数据的包。致敬技术,希望你变得更强!