Chrome调试面板
常用面板![](https://img-blog.csdnimg.cn/60557d35a6e94f11a5be9bfb7d36e5cb.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6IuP5pmoNTA5,size_20,color_FFFFFF,t_70,g_se,x_16)
-
定位小箭头按钮(左边第一个): 选中Elements面板,并启动该按钮,可以在页面中定位相应元素的源代码位置,或者选择源代码位置可定位到页面相应的元素。
-
手机-PC视图切换按钮(左边第二个): 启动该按钮,网页可以在pc网址网页和手机网址网页之间进行转换。由于在爬虫过程中,爬取手机网址网页相对来说更容易,所以可以通过该按钮将网页切换至移动网页实现更快速爬取操作。
-
Elements面板(元素面板) 该面板显示了渲染完毕后的全部HTML源代码,在使用selenium爬取网页时可通过这些源代码找到各标签的位置,属性等特征。更重要的是,双击html源码或者右侧的css,可以更改网页外观,即可以对静态网页进行调试。
-
Console面板(控制台面板) 该面板用来显示网页加载过程中的日志信息,包括打印,警告,错误及其他可显示的信息等。同时它也是一个js交互控制台。
-
Sources面板(源代码面板) 该面板以站点为分组,存放着请求下来的所有资源(html,css,jpg,gif,js等)。正是因为该面板存放了所有的资源,因此在调试js时,目标代码都是在此处寻找的。该面板也提供了调试按钮工具。
-
Network面板(网络面板) Network面板记录了网络请求的详细信息,包括请求头,响应头,表单数据,参数信息等,
Network面板
-
all:所有的请求
-
XHR(XmlHttpRequest对象js生成): js动态加载请求
-
JS: JS代码
-
Css: 样式
-
image: 图片
-
Media: 音频,视频
-
Font: 字体
-
DOC: 首页
-
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代码 是重点