js渗透第一章baidu翻译

Chrome调试面板

常用面板

 

  1. 定位小箭头按钮(左边第一个): 选中Elements面板,并启动该按钮,可以在页面中定位相应元素的源代码位置,或者选择源代码位置可定位到页面相应的元素。

  2. 手机-PC视图切换按钮(左边第二个): 启动该按钮,网页可以在pc网址网页和手机网址网页之间进行转换。由于在爬虫过程中,爬取手机网址网页相对来说更容易,所以可以通过该按钮将网页切换至移动网页实现更快速爬取操作。

  3. Elements面板(元素面板) 该面板显示了渲染完毕后的全部HTML源代码,在使用selenium爬取网页时可通过这些源代码找到各标签的位置,属性等特征。更重要的是,双击html源码或者右侧的css,可以更改网页外观,即可以对静态网页进行调试。

  4. Console面板(控制台面板) 该面板用来显示网页加载过程中的日志信息,包括打印,警告,错误及其他可显示的信息等。同时它也是一个js交互控制台。

  5. Sources面板(源代码面板) 该面板以站点为分组,存放着请求下来的所有资源(html,css,jpg,gif,js等)。正是因为该面板存放了所有的资源,因此在调试js时,目标代码都是在此处寻找的。该面板也提供了调试按钮工具。

  6. Network面板(网络面板) Network面板记录了网络请求的详细信息,包括请求头,响应头,表单数据,参数信息等,

Network面板

 

  1. all:所有的请求

  2. XHR(XmlHttpRequest对象js生成): js动态加载请求

  3. JS: JS代码

  4. Css: 样式

  5. image: 图片

  6. Media: 音频,视频

  7. Font: 字体

  8. DOC: 首页

  9. WS: WebSocket

设置断点

目的:通过调试找到目标数据生成的地方 使用断点来暂停JavaScript代码,审查变量的值和在特定时刻所调用的堆栈。 设置断点的最基本的方法是在特定的代码行上手动添加一个断点。也可以将这些断点配置为仅在满足特定条件时触发。 在源代码的左侧,您可以看到行号。这个区域称为line number gutter(行号槽)。单击行号槽中的行号,就会在该行代码上添加一个断点。 例如事件,DOM更改。

逐步调试

 

作用域

当脚本中断的时候,Scope(作用域)窗格将显示当前时刻所有当前定义的属性。

 

调用堆栈

 

参数来源(重要)

不变的参数写固定值,变动的参数的来源在JS中寻找,即JS渗透 一个动态请求的参数来源只可能有两个: 一是来自之前的请求响应,二是JS生成

参数对比来源

 

query 是自己输入的数据

sign是动态加载的 token 可以从访问百度翻译-200种语言互译、沟通全世界!得到的静态页面中获取

获取token值

 

 

获取sign值

调试细节

底层函数

通过点击initiator 进入的代码,可能是一个底层的函数;多种动态请求均可以调用此函数;所以要通过请求的url判断,此次触发是否是目标请求的v2transapi

 

 

 

找到生成sign的函数

 

进入生成sign的函数

 

PyExecJs执行js代码

生成sign的js完整代码

function n(r, o) {
        for (var t = 0; t < o.length - 2; t += 3) {
            var a = o.charAt(t + 2);
            a = a >= "a" ? a.charCodeAt(0) - 87 : Number(a),
            a = "+" === o.charAt(t + 1) ? r >>> a : r << a,
            r = "+" === o.charAt(t) ? r + a & 4294967295 : r ^ a
        }
        return r
}
var i = null;
function e(r,gtk) {
        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 = gtk || "") || "";
        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)
    }

可能遇到的错误

代码实现

  • 靠近边栏顶部的是Call Stack(调用堆栈)窗格。当代码在断点处暂停时,CallStack(调用堆栈)窗格显示执行路径,按时间逆序,将代码带到该断点。这有助于理解现在执行到哪里,它是如何到达这里的,是调试的一个重要因素。

  • 调用函数链,下面调用上面的函数

  • 百度翻译请求分析

    参数构造流程

    这种提交数据得到响应的的请求,往往参数比较麻烦,所以参数的构造是得到完整请求的关键.

    以定位到URL为前提

  • 先作对比,找出不同的参数

  • 从之前的请求响应中找数据 (1)网页源代码中查找 (2)全局请求搜索

  • JS加载调试,查找生成规律

  • 定位url 查看数据

  •  

  • 进入initiator

  •  

  • 调整显示格式

  •  

  • 打断点

  •  

  • 遇到的错误1

    • 报错

    • 解决方法 js代码中添加以下代码

    • 遇到的错误2

      • 报错

      • 检查

      • js代码内容

      •  

      • 解决方法 找到window 的值,替换成固定的值,或从之前的请求中得到的值

      •  

  • 遇到的错误3

    • 错误

    •  

    • 解决方法 js代码中添加以下代码

      js代码中添加

    •  

注意:

import re
import  requests
import  execjs
​
#一获取token
url="https://fanyi.baidu.com/"
headers={"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36"}
session=requests.Session()
session.headers=headers
res1=session.get(url)
# print(res1.text)
token1=re.findall("token: '(.*?)'",res1.text)[0]
print(token1)
​
res2=session.get(url)
token2=re.findall("token: '(.*?)'",res2.text)[0]
print(token2)
​
res3=session.get(url)
token3=re.findall("token: '(.*?)'",res3.text)[0]
print(token3)
​
#二.获取sign
​
def  makeExecJsObj():
    with open("sign.js","r") as f:
        js=f.read()
        #生成对象
        return  execjs.compile(js)
get_sign=makeExecJsObj()
#执行函数
#获取gtk
res=session.get(url="https://fanyi.baidu.com/")
gtk=re.findall("window.gtk = '(.*?)'",res.text)[0]
query=input("输入汉语:")
sign=get_sign.call("e",query,gtk)
print(sign)
​
​
#三  构造formdata  发送请求
​
form_data={
    "from": "zh",
    "to": "en",
    "query": query,
    "transtype": "enter",
    "simple_means_flag": "3",
    "sign": sign,
    "token": token3,
    "domain": "common",
}
url="https://fanyi.baidu.com/v2transapi?from=zh&to=en"
res=session.post(url,data=form_data)
# print(res.text)
content=re.findall('"dst":"(.*?)"',res.text)[0]
print(content)

解决错误,完整js代码总结

  • token需要获取多次,才能保持稳定不变

  • PyexecJs执行 生成sign的js代码 是重点

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值