python requests 最新抓取百度翻译内容,js逆向,亲测有效

2023-05-16

python requests 抓取百度翻译 js破解 最新版

上一篇文章写了有道翻译抓取,朋友圈的大佬说试试抓取百度翻译!,于是我就抱着试一试的心态开始写了

目标网站:https://fanyi.baidu.com/?aldtype=16047

1.寻找数据
F12进去NetWork 调试多次,发现翻译后的数据放在json里
在这里插入图片描述
2.找出接口区别
下图(中翻英)接口下

在这里插入图片描述
下图是(日翻英)的接口
在这里插入图片描述
接口为:
https://fanyi.baidu.com/v2transapi?from={需要翻译的文字语言}&to={翻译成什么语言}
这两个参数的值会变化

3.分析表单
很明显该请求是POST类型,
在这里插入图片描述
发现 sign是随着输入不同而变化,相同输入生成的值相同(重点)。
token值一直不变,先找出来,全局搜索
在这里插入图片描述
观察发现,下面的langList不就是语言代码的一个映射吗。将他保存下来方便使用。
from和to很明显,跟你输入和想要翻译的结果语言对应。
query是需要翻译的内容,
其他几个参数都是不变的。

4. 破解js加密找出sign值
1.全局搜索sign
在这里插入图片描述
2.打断点-跟踪函数
可以看出来这是应该ajax请求,w里面的参数就是我们要找的参数。
在Sourth中找到刚才全局搜索到的js文件,然后搜索界面、打断点
在这里插入图片描述
鼠标悬停在f(n)上,会出现一个跳转,点击可以跳转到他的函数那里。
在这里插入图片描述
跳转后的函数为:
在这里插入图片描述
下一步:
扣代码生成sign值

function e(r){
        var o=r.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g);
        if(null===o){
            var t=r.length;t>30&&(r=""+r.substr(0,10)+r.substr(Math.floor(t/2)-5,10)+r.substr(-10,10))
        }else{
            for(var e=r.split(/[\uD800-\uDBFF][\uDC00-\uDFFF]/),C=0,h=e.length,f=[];
                 h>C;C++)""!==e[C]&&f.push.apply(f,a(e[C].split(""))),C!==h-1&&f.push(o[C]);
            var g=f.length;
            g>30&&(r=f.slice(0,10).join("")+f.slice(Math.floor(g/2)-5,Math.floor(g/2)+5).join("")+f.slice(-10).join(""))
        }
        var u=void 0,
            l=""+String.fromCharCode(103)+String.fromCharCode(116)+String.fromCharCode(107);u=null!==i?i:(i=window[l]||"")||"";
        for(var d=u.split("."),m=Number(d[0])||0,s=Number(d[1])||0,S=[],c=0,v=0;v<r.length;v++){
        var A=r.charCodeAt(v);
        128>A?S[c++]=A:(2048>A?S[c++]=A>>6|192:(55296===(64512&A)&&v+1<r.length&&56320===(64512&r.charCodeAt(v+1))?(A=65536+((1023&A)<<10)+(1023&r.charCodeAt(++v)),S[c++]=A>>18|240,
        S[c++]=A>>12&63|128):S[c++]=A>>12|224,
        S[c++]=A>>6&63|128),S[c++]=63&A|128)
    }
    for(var p=m,F=""+String.fromCharCode(43)+String.fromCharCode(45)+String.fromCharCode(97)+(""+String.fromCharCode(94)+String.fromCharCode(43)+String.fromCharCode(54)),D=""+String.fromCharCode(43)+String.fromCharCode(45)+String.fromCharCode(51)+(""+String.fromCharCode(94)+String.fromCharCode(43)+String.fromCharCode(98))+(""+String.fromCharCode(43)+String.fromCharCode(45)+String.fromCharCode(102)),b=0;b<S.length;b++)
    p+=S[b],p=n(p,F);
    return p=n(p,D),p^=s,0>p&&(p=(2147483647&p)+2147483648),
    p%=1e6,p.toString()+"."+(p^m)
    }

通过Python中的 PyExecJS 模块执行 js代码
首先安装:
执行命令:pip install PyExecJS
如果下载超时,执行pip install -i https://pypi.douban.com/simple PyExecJS

执行代码:

with open('bd_sign.js', 'r', encoding='utf-8') as f:
    ctx = execjs.compile(f.read())

sign = ctx.call('e', 'query')
print(sign)

报错了 显示’i’未定义在这里插入图片描述
这时我们返回浏览器中继续加断点调试 查看 i 值 是怎么生成的,在289行发发现i u = null !== i ? i : (i = window[l] || “”) || “”; 的,经过过多次尝试发现这里的i值是不变的,声明一下 i 在这里插入图片描述
再一次执行代码,有出现类似的错误,
在这里插入图片描述
检查js代码发现 变量n 未声明, 继续返回断点调试的地方,在function e®{}的前面发现function n(r,o){},将其加到代码顶端,

运行代码
在这里插入图片描述
生成的值与网站相同
在这里插入图片描述
sign逆向完成!

5.大致构建请求

想必逻辑已经很明了吧,难点就是js破解,已经解决。
百度翻译和有道翻译请求头headers都要传个Cookie ,可能是客户端的标识,不添加的话请求失败。在这里插入图片描述
6.实现代码

import requests
import execjs


class baiDuFy(object):
    def __init__(self, msg, comef, to):
        self.initial_url = 'https://fanyi.baidu.com/?aldtype=16047'
        # 从'comef'语言翻译为'to'语言
        self.comef = comef
        self.to = to
        self.url = 'https://fanyi.baidu.com/v2transapi?from={comef}&to={to}'.format(comef=self.comef, to=self.to)
        self.msg = msg

    def get_sign(self):
        with open('bd_sign.js', 'r', encoding='utf-8') as f:
            ctx = execjs.compile(f.read())

        sign = ctx.call('e', self.msg)
        return sign

    def get_result(self):
        data = {  # 翻译内容语言
            'from': self.comef,
            # 翻译后的语言
            'to': self.to,
            # 翻译内容
            'query': self.msg,
            # 固定值
            'transtype': 'translang',
            # 固定值
            'simple_means_flag': 3,
            # js生成(难点)
            'sign': self.get_sign(),
            # 固定值
            'token': '2446d432cd4cc5a879d46fd54300e38c',
            # 固定值
            'domain': 'common'
        }
        # X-Requested-With': 'XMLHttpRequest' 该请求是AJAX 异步请求,否则为同步请求, Cookie可以理解为客户端的标识,有效时间应该很长
        headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)'
                                 ' Chrome/88.0.4324.150 Safari/537.36',
                   'Referer': self.initial_url,
                   'X-Requested-With': 'XMLHttpRequest',
                   'Cookie': 'BIDUPSID=CA299524D71B0671D693C1DFA2B437CA; PSTM=1601733661;'
                             ' BAIDUID=CA299524D71B0671AE76F7C420FBBDE7:FG=1',
                   }
        resp = requests.post(self.url, data=data, headers=headers)
        return resp.json()['trans_result']['data'][0]['dst']


# 语言代码
lang_dict = {
    'zh': '中文', 'jp': '日语', 'jpka': '日语假名', 'th': '泰语', 'fra': '法语', 'en': '英语', 'spa': '西班牙语', 'kor': '韩语',
    'tr': '土耳其语', 'vie': '越南语', 'ms': '马来语', 'de': '德语', 'ru': '俄语', 'ir': '伊朗语', 'ara': '阿拉伯语', 'est': '爱沙尼亚语',
    'be': '白俄罗斯语', 'bul': '保加利亚语', 'hi': '印地语', 'is': '冰岛语', 'pl': '波兰语', 'fa': '波斯语', 'dan': '丹麦语', 'tl': '菲律宾语',
    'fin': '芬兰语', 'nl': '荷兰语', 'ca': '加泰罗尼亚语', 'cs': '捷克语', 'hr': '克罗地亚语', 'lv': '拉脱维亚语', 'lt': '立陶宛语', 'rom': '罗马尼亚语',
    'af': '南非语', 'no': '挪威语', 'pt_BR': '巴西语', 'pt': '葡萄牙语', 'swe': '瑞典语', 'sr': '塞尔维亚语', 'eo': '世界语', 'sk': '斯洛伐克语',
    'slo': '斯洛文尼亚语', 'sw': '斯瓦希里语', 'uk': '乌克兰语', 'iw': '希伯来语', 'el': '希腊语', 'hu': '匈牙利语', 'hy': '亚美尼亚语', 'it': '意大利语',
    'id': '印尼语', 'sq': '阿尔巴尼亚语', 'am': '阿姆哈拉语', 'as': '阿萨姆语', 'az': '阿塞拜疆语', 'eu': '巴斯克语', 'bn': '孟加拉语', 'bs': '波斯尼亚语',
    'gl': '加利西亚语', 'ka': '格鲁吉亚语', 'gu': '古吉拉特语', 'ha': '豪萨语', 'ig': '伊博语', 'iu': '因纽特语', 'ga': '爱尔兰语', 'zu':
    '祖鲁语', 'kn': '卡纳达语', 'kk': '哈萨克语', 'ky': '吉尔吉斯语', 'lb': '卢森堡语', 'mk': '马其顿语', 'mt': '马耳他语', 'mi': '毛利语',
    'mr': '马拉提语', 'ne': '尼泊尔语', 'or': '奥利亚语', 'pa': '旁遮普语', 'qu': '凯楚亚语', 'tn': '塞茨瓦纳语', 'si': '僧加罗语',
    'ta': '泰米尔语', 'tt': '塔塔尔语', 'te': '泰卢固语', 'ur': '乌尔都语', 'uz': '乌兹别克语', 'cy': '威尔士语', 'yo': '约鲁巴语', 'yue':
    '粤语', 'wyw': '文言文', 'cht': '中文繁体'}

bd = baiDuFy('おはようございます', comef='jp', to='en')
res = bd.get_result()
print(res)

运行结果为:
在这里插入图片描述
亲测有效,本文章全系对技术的兴趣爱好,欢迎大家学习交流。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

python requests 最新抓取百度翻译内容,js逆向,亲测有效 的相关文章

随机推荐