Python爬虫中如何通过post发请求,浏览器控制台抓包教程,有道翻译爬虫程序,通过python伪装翻译(post案例) - Go语言中文社区

Python爬虫中如何通过post发请求,浏览器控制台抓包教程,有道翻译爬虫程序,通过python伪装翻译(post案例)


目录

一、浏览器控制台抓包

1.打开方式以及常用选项

2.控制台NetWrok  

二、Python爬虫中如何通过post发请求

1.Post请求

2.Python中使用post请求

三、有道翻译爬虫程序,通过python伪装翻译(post案例)

1.需求分析

2.post请求分析

3.js方法转python方法

4.程序设计


一、浏览器控制台抓包

在很多的工作中都是需要进行抓取到网络的相关数据进行分析,来进行查看访问到服务器返回的数据是否正确,来判断是否是自己想要的数据,可以通过这些数据做相关内容测试,和二次开发,常用的接口测试方法。

1.打开方式以及常用选项

打开浏览器,按F12打开控制台或者右键点击检查。控制台界面如下,右侧即为控制台。控制台有数个选项,我们依次来说。

Elements:查看元素节点位置,看到Elements左侧的鼠标按钮(或者Ctrl+shift+c),选中后点击网页文件的任意位置,Elements栏会显示鼠标停留地方的Elements节点属性。

Console:控制台,交互模式,可以对JavaScript代码进行测试。

Sources:格式化输出并可以打断点调试JS代码,助于分析爬虫中一些参数。

Performance:主要用于做前端性能优化,可以监控到毫秒级别,网络,cpu等性能在数据收发时的状态。

 

 

2.控制台NetWrok  

NetWrok的作用是查看被抓取网络数据包,也可以检查cookies,Headers请求头等信息。下图是Network工作图以及一些被抓取到的网络文件。

ALL:抓取所有的网络数据包

XHR:抓取异步加载的网络数据包,如Ajax文件

JS:抓取所有的JS文件

CSS:抓取样式文件

Img/Media:抓取图片,视频

下图是cookies的信息,比如我们账号密码也包含在里面:

 

二、Python爬虫中如何通过post发请求

1.Post请求

我们在使用Python做爬虫的时候,通常使用的是requests模式的get()方法,这里介绍Post方法。做过前端的应该知道,前端页面要提交请求有post和get方法,post可以隐藏参数,也可以对传输内容加密,一般在表单(from)数据中,我们进行登录也是用的表单提交,还有各种网站的注册信息也是。在网页中,除了我们通过url访问网页时用get方法外,只要你用得着提交数据的,绝大多是都是用的post请求。

2.Python中使用post请求

在python中用post请求很容易,需用用到requests模块,与get方法不同的是,post方法需要传入data方法,data在这里是一个字典,用于装提交的参数信息。

rep=requests.post(url,data,headers) 

 

三、有道翻译爬虫程序,通过python伪装翻译(post案例)

1.需求分析

打开有道翻译首页,url:http://fanyi.youdao.com/ 

我们要做的就是用python提交请求翻译的内容,然后由python接受,其实就相当于用电脑来模拟人的操作,有什么用呢,主要有两点:

1)适合大批量翻译:对于较多的翻译内容,用机器来请求比人手动点击要效率高的多

2)作为第三方插件:当你在设计自己的程序代码时,如果要用到翻译的功能,你可以自己写一个翻译程序,其难度可想而知,也可以写一套爬虫程序,将某个第三方的爬虫程序作为你程序的一部分,非常节省时间。

我们下面要做的就是写一段python爬虫程序,来提交翻译请求。如果用get肯定是不行的,get将参数与url一起发给接收方。但是有道明显不是这么做的,在发请求前后url没有发生变化,说明他是通过post发送的请求。如图所示。

 

总结:按照需求,我们要用python来发送请求和接受结果,以此实现翻译功能,本程序的核心在与如何生成post请求表达(form),下面进一步分析。

 

2.post请求分析

我们的目的旨在分析在发送post请求时,浏览器到底封装了什么数据(表单数据),也就是data中究竟要装什么,才能伪装成浏览器向服务器端发送请求。下面我们来翻译进行一次翻译,如图,翻译后,进入控制台界面,点击网络,在XHR中找到了请求表达,也就是说有道翻译是基于AJAX+JS发送请求的,查看此Ajax文件,我们看到了他的请求头:

 

下面我们一个个来分析请求头中的内容,以下是全部内容,是我对每个文本的解释,可能并不准确:

i很好理解,就是我们请求的对象(翻译对象),from谁发起的,to发给谁,smartresult直接返回,client客户端类型(这里是web浏览器),salt/ts/bv不详,doctype为json数据类型,版本2.1,keyfrom应该是key来自谁(这里是web浏览器),action动作立即执行。

i:我是一匹狼

from:AUTO

to:AUTO

smartresult:dict

client:fanyideskweb

salt:15818489372401

sign:7c2431437f3312132086089fcbad13d0

ts:1581848937240

bv:bc250de095a39eeec212da07435b6924

doctype:json

version:2.1

keyfrom:fanyi.web

action:FY_BY_REALTlME

 也就是说,我们只需要把这些东西丢到post请求的data中去,就可以模拟浏览器进行请求,但是问题来了,这些内容哪些是变化的哪些是不变的?当然第一个变化的肯定是i属性,也就是我们请求翻译的对象,我们还需要找到其他变化的属性。我们再启动一个浏览器,打开有道翻译,我这里是打开的火狐浏览器,并且进行了一次请求,如下图。

我们通过对比两组表单数据来找出不同的地方,经过分析,我找出了4个会变化的属性(i可以忽略,实际只有3个)。接下来我们要分析这些属性为什么会变化。

谷歌:

i:我是一匹狼

salt:15818489372401

sign:7c2431437f3312132086089fcbad13d0

ts:1581848937240

火狐:

i:沧海桑田

salt:15818489372401

sign:7c2431437f3312132086089fcbad13d0

ts:1581848937240

 到目前为止,我们知道这些表单数据是Ajax+js来进行请求的,所以要分析这些属性为什么会变化,就要去js文件中查看代码,看看其js文件怎么写的,要找到这些属性出现在哪个js文件中,我们按ctrl+f弹出搜索框,在窗口输入salt:,果然有一个结果,点击此js文件进入代码区。

 点击后,在Response处会显示出代码,但是格式比较乱,点击我图中划线的那个{},系统会自动编排格式。把鼠标停留在代码区里,按ctrl+shift+f,弹出搜索框,搜索salt:

 

一共看到四个结果,第一个结果是对属性的封装,不是我们要找的,看到第二个结果,这就是我们想看的了。 

 第二个结果很明显的写出了ts,bv,salt,sign是的数据是如何产生的,我们现在一个个进行分析:

 

1)ts

ts很好理解,js代码显示为当前时间:"" + (new Date).getTime(),并且还将这个时间转换为了字符串。是一个13位的字符串.

2)salt

r + parseInt(10 * Math.random(), 10);这个也很好理解,就是把前的bv加上一个0-10的随机数。

3)sign

n.md5("fanyideskweb" + e + i + "n%A-rKaT5fb[Gy?;N5@Tj")。使用md5进行加密,"fanyideskweb"一串字符串,为固定格式,e目前不知道是什么,i就是salt,再加上"n%A-rKaT5fb[Gy?;N5@Tj"一段固定字符串。

我们进一步分析这个e是什么,在8373行加上断点(断点调试),在翻译框中重新输入一段文字,可以看到这个e到底是什么,原来就是我们要翻译的内容,现在我们知道e是什么了,所有的分析已经over。

 

总结:

1.ts:"" + (new Date).getTime()

2.salt:r + parseInt(10 * Math.random(), 10);

3.sign:n.md5("fanyideskweb" + e + i + "n%A-rKaT5fb[Gy?;N5@Tj"),e是翻译内容

 

3.js方法转python方法

我们现在要做的就是把js方法转换为python方法,让python能够输出同样的结果。

1)ts:"" + (new Date).getTime()

python中调用时间的模块是time,与js不同的是python只生成10位,而js生成13位,所以要给python的time方法在乘以1000,最好将它转换成字符串即可,如下:

import time
ts=str(int(time.time()*1000))

2)salt:r + parseInt(10 * Math.random(), 10);

这个好写,r是ts,也就是ts加一个0-9的随机数(js方法上的10代表10以内),python代码为

import random
import time 
ts=str(int(time.time()*1000))
salt=ts+str(random.randint(0,9))

3)sign:n.md5("fanyideskweb" + e + i + "n%A-rKaT5fb[Gy?;N5@Tj")

import hashlib
sign="fanyideskweb"+e+salt+str(hashlib.md5("123".encode()).hexdigest())+"n%A-rKaT5fb[Gy?;N5@Tj")

 

4.程序设计

本程序一共4个函数:

1.__init__():初始化参数,重点在于包装请求头,有代理的可以写上代理,我没有代理所以不写

2.make_Data():用户封装data,关键在于三个变动参数的生成

3.translate():用于请求翻译并取得结果

4.run():函数执行入口

import time
import random
import hashlib
import requests

class YoudaoTranslate(object):

    #初始化参数
    def __init__(self):
        #请求的url
        self.url="http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule"
        #封装请求头,要求和网易请求一致
        self.headers={
            "Accept": "application/json, text/javascript, */*; q=0.01",
            "Accept-Encoding": "gzip, deflate",
            "Accept-Language": "zh-CN,zh;q=0.9",
            "Connection": "keep-alive",
            "Content-Length": "278",
            "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
            "Cookie": "OUTFOX_SEARCH_USER_ID=-615698648@10.169.0.83; JSESSIONID=aaaLYHK5MHJzKbVCpznbx; OUTFOX_SEARCH_USER_ID_NCOO=2145091673.4136953; ___rl__test__cookies=1581848937227",
            "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/78.0.3904.108 Safari/537.36",
            "X-Requested-With": "XMLHttpRequest",
        }
        # 如果有代理可以写代理
        # self.proxies={
        #     'http':'http://',
        #     'https':'https://'
        # }

    #该函数用于封装data
    def make_Data(self,text):
        e=text
        ts=str(int(time.time()*1000))
        salt=ts+str(random.randint(0,9))
        string="fanyideskweb"+e+salt+"n%A-rKaT5fb[Gy?;N5@Tj"
        sign=hashlib.md5(string.encode()).hexdigest()
        return ts,salt,sign

    #该函数用于请求翻译结果
    def translate(self,text):
        ts,salt,sign=self.make_Data(text)
        #定义data,替换ts,salt,sing的值
        data = {
            'i': text,
            'from': 'AUTO',
            'to': 'AUTO',
            'smartresult': 'dict',
            'client': 'fanyideskweb',
            'salt': salt,
            'sign': sign,
            'ts': ts,
            'bv': 'bc250de095a39eeec212da07435b6924',
            'doctype': 'json',
            'version': '2.1',
            'keyfrom': 'fanyi.web',
            'action': 'FY_BY_REALTlME',
        }
        #用post做请求,获得json输出,便于我们提取数据
        #请求结果格式为:{"translateResult":[[{"tgt":"Who are you","src":"你是谁"}]],"errorCode":0,"type":"zh-CHS2en","smartResult":{"entries":["","Who are yourn"],"type":1}}
        rep=requests.post(url=self.url,data=data,headers=self.headers).json()
        result=rep["translateResult"][0][0]["tgt"]
        return result

   #入口函数
    def run(self):
        text=input("输入被翻译内容:")
        result=self.translate(text)
        print("翻译结果为:",result)

if __name__=="__main__":
    translate=YoudaoTranslate()
    translate.run()

执行效果: 

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/ck784101777/article/details/104340693
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢