油猴脚本记(含检测)
写脚本
模拟爬取市面上网站(淘宝、京东、美团等)的页面内容
油猴脚本是通过JS来编写,我也才接触只是对dom进行操作来完成
- 首先是@match需要设置,就是用来说明脚本在哪个页面执行
- 接下来就是写脚本,主要思路是
- 页面分为列表页,从列表页可以进入详情页。那么脚本就设置在列表页进行
- 为了直观显示,将在列表页创建一个iframe用来显示爬取的详情页
- 模拟用户去点击每一个商品操作,这样子做轮询
- 实现
- 列表页:获取当前的页面,获取商品数,获取每个商品的链接
- 创建iframe,加载商品的链接
- 两个函数做递归,在加载第二个商品时候需要将第一个iframe删除
// ==UserScript==
// @name (自定义随意)
// @namespace http://tampermonkey.net/
// @version 0.1
// @description try to take over the world!
// @author You
// @match (模板https://xxx.com/xxx/*)来匹配需要之行脚本的页面
// @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
// @grant none
// ==/UserScript==
(function() {
'use strict';
var content = document.getElementsByClassName("info--wrap"); //获取当前页面的所有商品
var nowIndex=0;//起始页数
var page=document.getElementsByTagName("strong")[1].innerText;//当前页
var ScrapyFunc=function(o){
var iframeDocument=o.contentDocument; //对iframe进行dom操作
console.log(nowIndex);
//var title = iframeDocument.getElementsByClassName("info-basic__right");
//console.log(title[0].innerText);
setTimeout(function(){LoopFunc()},3000);
};
var LoopFunc=function(){
if(nowIndex>=content.length){
page ;
window.location.replace('https://bj.58.com/ershouche/pn' page '/');//加载到下一页
}
var url = content[nowIndex ].innerHTML.split('"')[3];
console.log(url);
var now_car_info_i = document.getElementsByClassName("cariframe");
if(now_car_info_i.length != 0)now_car_info_i[0].parentNode.removeChild(now_car_info_i[0]); //调用父删除iframe
var iframe = document.createElement("iframe"); //创建iframe
iframe.src = url;
iframe.className = 'cariframe';
iframe.height="300";
iframe.width="1280";
if (iframe.attachEvent){ //判断iframe是否加载完成
iframe.attachEvent("onload",function(){ScrapyFunc(iframe)});
} else {
iframe.onload =function(){ScrapyFunc(iframe)};
}
document.body.insertBefore(iframe, document.body.children[0]); //将iframe放在页面顶端
};
LoopFunc();
})();
踩坑
- 如果页面是https,那么iframe也必须是https,如果iframe是http那么需要从浏览器中去单独的设置,否则浏览器是会报错无法显示frame内容
- 使用setTimeout()函数达到延迟效果,有时由于网络问题页面还没有加载完成,这是如果进行了dom操作会报错,所以可以进行短暂的延时让页面加载一会。setTimeout()直接使用可能不生效需要下成如下样式:
setTimeout(function(){xxxxxxxxxxx},3000);
检测脚本
脚本的运行原理
油猴脚本是在沙盒里执行用户脚本,不会对网页注入script元素,它通过沙盒向网页中传递信息以达到控制dom的操作。所以如果要对脚本进行检测,没有像上面代码这样子向页面中植入iframe的话,通过去检测dom和window是无法检测出使用油猴脚本的。
检测方法一
通过鼠标点击事件检测,正常的用户使用鼠标点击按钮会有一个坐标,但是动过click()函数进行的点击操作是没有坐标的。所以可以通过这个方式做简单的验证,测试一下
代码语言:javascript复制//点击事件的坐标
document.addEventListener('click',(e)=>{console.log(e.clientX,e.clientY)})
- 正常鼠标点击
- 使用click()进行点击
检测方法二
使用isTrusted事件进行识别,这个事件可以判断是否是人进行点击或者是js模拟点击,当是手动点击会返回true,否则会返回false
Js代码如下:
代码语言:javascript复制document.querySelector("#bt").addEventListener("click",
function(event) {
console.log('被点击,isTrusted值为:');
console.log(event.isTrusted);
});
测试
结
对于油猴脚本的检测难度是比较大的,但应该还是有其他的办法,后续也会对其进行研究。同时也可以通过用户的行为等方式来辅助的进行判断,因为人工去点击和脚本去执行操作还是有很大的不同。
Q.E.D.