爬虫----POST 请求

场景

需要使用Form表单提交数据的请求。

import requests
headers = {"UserAgent":"xxx"}
data = {"user":"lauf","pw":"123"}

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

抓包工具

https://fanyi.youdao.com/
页面分析:
静态页面还是动态页面
静态页面,响应html文件,数据固定在页面中
动态页面,响应json数据,数据在页面中会变换

  1. 输入要翻译的中文,会返回英文
    在这里插入图片描述
    preview,预览
    静态页面会渲染显示
    json 数据会格式化输出

在这里插入图片描述

  1. F12 开发者模式/右键-检查
    Network,抓网络数据包
    All,所有的数据包
    XHR,异步加载 的数据包
    JS,CSS,… 相应的文件

Sources,格式化输出js代码,并打断点测试js 代码(点击执行的行号),分析js加密的参数
Console,控制台,交互式测试js,输入代码,查看结果

在这里插入图片描述
3.批量转为字典数据

批量的key-value 数据,转为字典形式

"""
i: 爱学习
from: AUTO
to: AUTO
smartresult: dict
client: fanyideskweb
salt: 16194411822602
sign: 4f332dd52402aa147cc451a6d0b37874
lts: 1619441182260
bv: 62c1eba97402d4ff4eb261254e974c27
doctype: json
version: 2.1
keyfrom: fanyi.web
action: FY_BY_REALTlME
"""

复制到pycharm中—>Ctrl+r—>regexp
如下:
在这里插入图片描述
请求头也可以完全模拟浏览器

POST提交的数据

看数据哪些是变化的,哪些是不变的
在这里插入图片描述
变化的数据:
javascript加密的
点击JS的网络数据包,查看js文件—>很多js文件,看哪个?
在这里插入图片描述
输入关键字搜索,如下:
在这里插入图片描述
断点测试:
在这里插入图片描述
输入单词,触发xhr,执行到断点处。恢复断点再次点击行号----resume script execute

解析出加密使用的算法,使用python 生成一遍,再放入程序中使用

解析结果
在这里插入图片描述

案例

需求分析
要求输入一个中文/英文
得到翻译的结果

"""
	1.分析页面,动态还是静态
	2.动态页面,抓XHR数据包 F12-->Network-->XHR
	从中获取请求的url、请求头、表单数据
	3.检查表单数据中的变与不变
	4.解析表单数据中的变化的部分,通常是js加密-->JS-->搜索关键字
	5.解析出加密算法,使用python生成加密数据,放入表单数据中
	6.发送POST 请求,解析响应
"""
import requests
import time
import hashlib
import random


class FYSpider(object):
    def __init__(self):
        # 异步请求的url
        self.url = "https://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule"
        self.headers = {
            "Accept": "application/json, text/javascript, */*; q=0.01",
            "Accept-Encoding": "gzip, deflate, br",
            "Accept-Language": "zh-CN,zh;q=0.9",
            "Connection": "keep-alive",
            "Content-Length": "252",
            "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
            "Cookie": "OUTFOX_SEARCH_USER_ID=-1357302210@171.9.140.217; OUTFOX_SEARCH_USER_ID_NCOO=1038748019.8050627; _ntes_nnid=5cc1dd34016abb2f5e1ccb332bf6366c,1616832815260; JSESSIONID=aaaD96LdPa6wu7JB14oKx; ___rl__test__cookies=1619452488346",
            "Host": "fanyi.youdao.com",
            "Origin": "https://fanyi.youdao.com",
            "Referer": "https://fanyi.youdao.com/",
            "sec-ch-ua": "Not A;Brand;v=99, Chromium;v=90, Google Chrome;v=90",\
            "sec-ch-ua-mobile":"?0","Sec-Fetch-Dest": "empty",
        """Sec-Fetch-Mode""": """cors""",
        """Sec-Fetch-Site""": """same-origin""",
        """User-Agent""": """Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36""","""X-Requested-With""": """XMLHttpRequest"""}  # 完全模拟浏览器/检查频率高的key


        self.data = {

            "i": None,
            "from": "AUTO",
            "to": "AUTO",
            "smartresult": "dict",
            "client": "fanyideskweb",
            "salt": None,
            "sign": None,
            "lts": None,
            "bv": "62c1eba97402d4ff4eb261254e974c27",
            "doctype": "json",
            "version": "2.1",
            "keyfrom": "fanyi.web",
            "action": "FY_BY_REALTlME",
        }  # 先设置不变的部分

    # 产生加密的数据
    def get_ts_salt_sign(self, word):
        # lts 毫秒级时间戳
        lts = str(int(time.time() * 1000))
        # salt 毫秒级时间戳+一个0-9的随机数
        salt = lts + str(random.randint(0, 9))
        # sign "fanyideskweb"+"你好"+salt+"Tbh5E8=16U3EXe+&L[4c@"-->md5加密
        sign_ = "fanyideskweb" + word + salt + "Tbh5E8=q6U3EXe+&L[4c@"
#          n.md5("fanyideskweb" + e + i + "Tbh5E8=q6U3EXe+&L[4c@"
        m = hashlib.md5()
        m.update(sign_.encode())
        sign = m.hexdigest()

        return lts, salt, sign

    def request_yd(self, word):
        lts, salt, sign = self.get_ts_salt_sign(word)
        self.data["lts"] = lts
        self.data["salt"] = salt
        self.data["sign"] = sign
        self.data["i"] = word
        # 发请求
        print(self.url)
        print(self.headers)
        print(self.data)
        self.res = requests.post(self.url, headers=self.headers, data=self.data)
        if self.res.status_code == 200:
            print("响应OK")
            print("响应内容",self.res.text)
        else:
            print("响应失败", self.res.status_code)

    def run(self, word):
        self.request_yd(word)
        print(self.res.text)  # 字符串
        print(self.res.json())  # json数据


if __name__ == "__main__":
    spider = FYSpider()
    spider.run("你好")
  • 6
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

laufing

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值