目标url:
- aHR0cHM6Ly91c2VyLnF1bmFyLmNvbS9wYXNzcG9ydC9sb2dpbi5qc3A=
实现难点:
- 逆向滑块请求
- 发送短信登录
目录
- 每篇前言:
- 0、前置技术栈
- (1)JS实现页面滑动
- (2)JS实现记录滑动轨迹
- (3)补基础浏览器环境
- (4)补环境
每篇前言:
🏆🏆作者介绍:【孤寒者】—CSDN全栈领域优质创作者、HDZ核心组成员、华为云享专家Python全栈领域博主、CSDN原力计划作者
- 🔥🔥本文已收录于爬虫进阶+实战系列教程专栏:《爬虫进阶+实战系列教程》
- 🔥🔥热门专栏推荐:《Python全栈系列教程》、《爬虫从入门到精通系列教程》、《爬虫进阶+实战系列教程》、《Scrapy框架从入门到实战》、《Flask框架从入门到实战》、《Django框架从入门到实战》、《Tornado框架从入门到实战》、《前端系列教程》。
- 📝📝本专栏面向广大程序猿,为的是大家都做到Python全栈技术从入门到精通,穿插有很多实战优化点。
- 🎉🎉订阅专栏后可私聊进一千多人Python全栈交流群(手把手教学,问题解答); 进群可领取Python全栈教程视频 + 多得数不过来的计算机书籍:基础、Web、爬虫、数据分析、可视化、机器学习、深度学习、人工智能、算法、面试题等。
- 🚀🚀加入我一起学习进步,一个人可以走的很快,一群人才能走的更远!
0、前置技术栈
(1)JS实现页面滑动
简单实现单击鼠标左键,控制台打印鼠标移动事件信息,松开左键后取消打印。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><div onmousedown="doDown(event)">滑动例子</div><script>function doDown(e){console.log("doDown", e);// 添加鼠标移动事件document.addEventListener("mousemove", doMove);document.addEventListener("mouseup", doUp);}function doMove(e){console.log("doMove", e)}function doUp(e){console.log("doUp", e)document.removeEventListener("mousemove", doMove);document.removeEventListener("mouseup", doUp);}
</script></body>
</html>
(2)JS实现记录滑动轨迹
下述有关轨迹的模拟生成,是根据本文目标网站提取的核心逻辑!
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><div onmousedown="doDown(event)">滑动例子</div><script>t = {state: {},sliderInfo: {track: [],deviceMotion: []}}function doDown(e){// n = e n.clientX是点击的x坐标var n = (e.changedTouches || e.touches || [e])[0];t.state.downX = n.clientX;console.log("开始x坐标:", n.clientX)console.log("doDown", e);// 添加鼠标移动事件document.addEventListener("mousemove", doMove);document.addEventListener("mouseup", doUp);}function doMove(e){var o = (e.changedTouches || e.touches || [e])[0];var n = t.state.downX;// o就是当前滑动的event; o.clientX就是当前滑动的x坐标; n是最开始点击的x坐标;// o.clientX - n 就是滑动距离!var u = (e = e || window.event, o.clientX - n);var n = u;var i = Date.now() % 1e5, // 获取一个随机数s = (e.changedTouches || e.touches || [e])[0],o = s.clientX.toFixed(2), // 将数字保留2个小数位数并返回一个字符串u = s.clientY.toFixed(2),a = n.toFixed(2),// “i;横坐标;纵坐标;滑动距离"f = "".concat(i, ";").concat(o, ";").concat(u, ";").concat(a);// 核心t.sliderInfo.track.push(f);// 也是轨迹window.addEventListener("deviceorientation", function (e) {t.sliderInfo.deviceMotion.push(e)}, !1)console.log("滑动过程u:", u)console.log("doMove", e)}function doUp(e){console.log("doUp", e)document.removeEventListener("mousemove", doMove);document.removeEventListener("mouseup", doUp);console.log(t.sliderInfo.track)console.log(t.sliderInfo.deviceMotion)}
</script></body>
</html>
(3)补基础浏览器环境
在使用pyexecjs执行JavaScript代码时(因为使用的nodejs引擎来执行的JavaScript代码,有别于浏览器),如果存在读取浏览器环境,就会失败报错。如:
此时,就需要创造浏览器环境然后再执行JavaScript代码:
npm config set registry https://registry.npm.taobao.orgnpm install -g jsdom
npm install -g node-gyp
npm install -g canvas --canvas_binary_host_mirror=https://npm.taobao.org/mirrors/canvas/
可以通过命令:npm root -g
来查看npm安装目录~
模块安装完成之后,需要将npm root -g
查到的npm安装目录添加到系统环境变量中:
安装完毕后,就可以通过上述模块补浏览器环境:
const jsdom = require("jsdom");
const {JSDOM} = jsdom;// 模拟浏览器打开https://www.toutiao.com,页面内容就是html
const html = '<!DOCTYPE html><p>Hello world</p>';
const dom = new JSDOM(html, {url: "https://www.toutiao.com",referer: "https://example.com",contentType: "text/html"
});// 下面就是补浏览器环境
document = dom.window.document;window = global;
Object.assign(global, {location: {hash: "",host: "user.qunar.com",hostname: "user.qunar.com",href: "https://user.qunar.com/passport/login.jsp",origin: "https://user.qunar.com",pathname: "/",port: "",protocol: "https:",search: "",},navigator: {appCodeName: "Mozilla",appName: "Netscape",appVersion: "5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36",cookieEnabled: true,deviceMemory: 8,doNotTrack: null,hardwareConcurrency: 4,language: "zh-CN",languages: ["zh-CN", "zh"],maxTouchPoints: 0,onLine: true,platform: "MacIntel",product: "Gecko",productSub: "20030107",userAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36",vendor: "Google Inc.",vendorSub: "",webdriver: false}
});location = window.location
只要在js文件中加入上述代码,运行就ok了!
(4)补环境
上述示例只是补充了浏览器中常见的window、document对象,抠出来的js代码中可能还有其他的值和变量,此时就需要根据环境提示来进行补环境:
- python运行js代码,分析报错信息
- 补充&测试
比如js代码中有这么一句:
var xhr = new XMLHttpRequest();
上述所补环境就不够,就会报错:
这时候就需要了解下XMLHttpRequest是啥?
简单说几句:
- 所有Ajax请求底层都是基于XMLHttpRequest。所以这个玩意就是发送Ajax请求用,一般情况下,这种js代码是跟算法逻辑无关的,所以直接补充这个对象,相应三个函数给空,不让js代码报错即可!
xhr = new XMLHttpRequest();
xhr.onreadystatechange = function (){if(xhr.readyState == 4){// 成功接收到响应数据var data = xhr.responseText;console.log(data);}
};
xhr.open('POST', '/test/', true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8');
xhr.send('n1=1;n2=2;');
补环境:
XMLHttpRequest = function() {return {open: function(){},setRequestHeader: function(){},send: function(){}}
}
这样的话,扣下来的js代码中有类似下图代码也就没问题了~