爬虫的奇技淫巧之ajax-hook

news2024/11/15 11:32:54

声明

本文仅供学习参考,如有侵权可私信本人删除,请勿用于其他途径,违者后果自负!

前言

随着反爬力度的不断升级,现在的爬虫越来越难搞了。诸如加密参数sign、signature、token。面对这种情况传统的方式可以使用自动化程序,如selenium、pyppeteer等。但是使用自动化工具会有很多特征能够被检测,对于爬虫工程师也很不友好。

正所谓道高一尺魔高一丈,这些难题怎么能难到我们呢?

今天介绍一个工具,ajax-hook。知名见意,对于网页中ajax的hook。
具体怎么hook,可以看一下源码,在这里不再解释。
参考链接:ajax-hook

小试牛刀

简单的了解过这个工具后,怎么使用呢。可以参考一下大佬的文章。
链接:爬虫神器!用它可以实时处理和保存 Ajax 数据

文章的内容在这里我已经测试过了没有问题,感兴趣的小伙伴可以自己去做一遍。

之前有小伙伴问我对于某音的视频评论有什么好的方法,这篇文章就使用ajax-hook去抓取评论数据。

  • 项目地址

    • Github地址:https://github.com/wendux/Ajax-hook
    • 源码:https://unpkg.com/ajax-hook@2.1.3/dist/ajaxhook.min.js

需要使用的源码在这里直接贴出来。

//# sourceMappingURL=ajaxhook.min.js.map
!function(t,e){for(var n in e)t[n]=e[n]}(window,function(t){function e(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return t[r].call(o.exports,o,o.exports,e),o.l=!0,o.exports}var n={};return e.m=t,e.c=n,e.i=function(t){return t},e.d=function(t,n,r){e.o(t,n)||Object.defineProperty(t,n,{configurable:!1,enumerable:!0,get:r})},e.n=function(t){var n=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(n,"a",n),n},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=3)}([function(t,e,n){"use strict";function r(t,e){var n={};for(var r in t)n[r]=t[r];return n.target=n.currentTarget=e,n}function o(t,e){function n(e){return function(){var n=this.hasOwnProperty(e+"_")?this[e+"_"]:this.xhr[e],r=(t[e]||{}).getter;return r&&r(n,this)||n}}function o(e){return function(n){var o=this.xhr,i=this,s=t[e];if("on"===e.substring(0,2))i[e+"_"]=n,o[e]=function(s){s=r(s,i),t[e]&&t[e].call(i,o,s)||n.call(i,s)};else{var u=(s||{}).setter;n=u&&u(n,i)||n,this[e+"_"]=n;try{o[e]=n}catch(t){}}}}function i(e){return function(){var n=[].slice.call(arguments);if(t[e]){var r=t[e].call(this,n,this.xhr);if(r)return r}return this.xhr[e].apply(this.xhr,n)}}return e=e||window,e[u]=e[u]||e.XMLHttpRequest,e.XMLHttpRequest=function(){for(var t=new e[u],r=0;r<a.length;++r){var c="on"+a[r];void 0===t[c]&&(t[c]=null)}for(var f in t){var h="";try{h=s(t[f])}catch(t){}"function"===h?this[f]=i(f):Object.defineProperty(this,f,{get:n(f),set:o(f),enumerable:!0})}var d=this;t.getProxy=function(){return d},this.xhr=t},Object.assign(e.XMLHttpRequest,{UNSENT:0,OPENED:1,HEADERS_RECEIVED:2,LOADING:3,DONE:4}),e[u]}function i(t){t=t||window,t[u]&&(t.XMLHttpRequest=t[u]),t[u]=void 0}Object.defineProperty(e,"__esModule",{value:!0});var s="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t};e.configEvent=r,e.hook=o,e.unHook=i;var u="__xhr",a=e.events=["load","loadend","timeout","error","readystatechange","abort"]},function(t,e,n){"use strict";function r(t,e){if(e=e||window,e.__xhr)throw"Ajax is already hooked.";return f(t,e)}function o(t){(0,h.unHook)(t)}function i(t){return t.replace(/^\s+|\s+$/g,"")}function s(t){return t.watcher||(t.watcher=document.createElement("a"))}function u(t,e){var n=t.getProxy(),r="on"+e+"_",o=(0,h.configEvent)({type:e},n);n[r]&&n[r](o);var i;"function"==typeof Event?i=new Event(e,{bubbles:!1}):(i=document.createEvent("Event"),i.initEvent(e,!1,!0)),s(t).dispatchEvent(i)}function a(t){this.xhr=t,this.xhrProxy=t.getProxy()}function c(t){function e(t){a.call(this,t)}return e[g]=Object.create(a[g]),e[g].next=t,e}function f(t,e){function n(t,e){var n=new w(t),r={response:e.response||e.responseText,status:e.status,statusText:e.statusText,config:t.config,headers:t.resHeader||t.getAllResponseHeaders().split("\r\n").reduce(function(t,e){if(""===e)return t;var n=e.split(":");return t[n.shift()]=i(n.join(":")),t},{})};if(!d)return n.resolve(r);d(r,n)}function r(t,e,n,r){var o=new E(t);n={config:t.config,error:n,type:r},v?v(n,o):o.next(n)}function o(){return!0}function a(t){return function(e,n){return r(e,this,n,t),!0}}function c(t,e){return 4===t.readyState&&0!==t.status?n(t,e):4!==t.readyState&&u(t,y),!0}var f=t.onRequest,d=t.onResponse,v=t.onError;return(0,h.hook)({onload:o,onloadend:o,onerror:a(p),ontimeout:a(l),onabort:a(x),onreadystatechange:function(t){return c(t,this)},open:function(t,e){var n=this,r=e.config={headers:{}};r.method=t[0],r.url=t[1],r.async=t[2],r.user=t[3],r.password=t[4],r.xhr=e;var o="on"+y;if(e[o]||(e[o]=function(){return c(e,n)}),f)return!0},send:function(t,e){var n=e.config;if(n.withCredentials=e.withCredentials,n.body=t[0],f){var r=function(){f(n,new b(e))};return!1===n.async?r():setTimeout(r),!0}},setRequestHeader:function(t,e){if(e.config.headers[t[0].toLowerCase()]=t[1],f)return!0},addEventListener:function(t,e){var n=this;if(-1!==h.events.indexOf(t[0])){var r=t[1];return s(e).addEventListener(t[0],function(e){var o=(0,h.configEvent)(e,n);o.type=t[0],o.isTrusted=!0,r.call(n,o)}),!0}},getAllResponseHeaders:function(t,e){var n=e.resHeader;if(n){var r="";for(var o in n)r+=o+": "+n[o]+"\r\n";return r}},getResponseHeader:function(t,e){var n=e.resHeader;if(n)return n[(t[0]||"").toLowerCase()]}},e)}Object.defineProperty(e,"__esModule",{value:!0}),e.proxy=r,e.unProxy=o;var h=n(0),d=h.events[0],v=h.events[1],l=h.events[2],p=h.events[3],y=h.events[4],x=h.events[5],g="prototype";a[g]=Object.create({resolve:function(t){var e=this.xhrProxy,n=this.xhr;e.readyState=4,n.resHeader=t.headers,e.response=e.responseText=t.response,e.statusText=t.statusText,e.status=t.status,u(n,y),u(n,d),u(n,v)},reject:function(t){this.xhrProxy.status=0,u(this.xhr,t.type),u(this.xhr,v)}});var b=c(function(t){var e=this.xhr;t=t||e.config,e.withCredentials=t.withCredentials,e.open(t.method,t.url,!1!==t.async,t.user,t.password);for(var n in t.headers)e.setRequestHeader(n,t.headers[n]);e.send(t.body)}),w=c(function(t){this.resolve(t)}),E=c(function(t){this.reject(t)})},,function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.ah=void 0;var r=n(0),o=n(1);e.ah={proxy:o.proxy,unProxy:o.unProxy,hook:r.hook,unHook:r.unHook}}]));
  • 项目实战

直接开始整吧,某音视频链接:aHR0cHM6Ly91bnBrZy5jb20vYWpheC1ob29rQDIuMS4zL2Rpc3QvYWpheGhvb2subWluLmpz

在这里插入图片描述
抓取的主要是评论内容和ip的归属地。

我这里使用的是油猴脚本注入。
在这里插入图片描述

ctrl+s后,重新刷新页面,发现扩展的油猴图标上面有一个红色的1,此时就说明该脚本已经成功注入到该网页了。

打开F12面板,向下翻动页面就可以看到console中源源不断的输出了内容,
在这里插入图片描述

认真比对一下发现想要的都在这里。

到这里项目就已经完成了1/3,现在的问题是怎么持久化本地去。

js中有很多可以发送网络请求的库,在这里推荐使用axios,像ajax-hook一样直接集成到油猴脚本里,然后在本地使用flask搭建一个web服务就可以源源不断的获取数据了。

脚本最终的代码:
在这里插入图片描述

本地web服务:
在这里插入图片描述

到这里就基本完成了,如何一直获取内容。可以使用自动化工具不断的向下滑动得到,或者内容不多也可以手滑。

我这里使用的是手滑,不过是用js自动滑动,这样更方便。
上网找了一段代码可以实现这个效果。

(function () {
    var height = document.body.clientHeight;
    var number = 0; //控制结束累加器
    var length = 0; //控制每次翻滚长度
    var frequency = 10000; //控制总时间
    var time = setInterval(function(){
    number += 1;
    if(number == frequency + 1){
        clearInterval(time);
    } else {
        //length += height /frequency ;
        length += height /50 ;
        document.documentElement.scrollTop = length;
    }
    },100); //每隔100MS翻滚一次
})()

方法同上。

最终看一下能不能实现自动滑动抓取内容的效果吧。

在这里插入图片描述

如果本文对你有帮助的话剋点赞收藏一波!

Alt

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/131650.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Redis集群系列九 —— 集群伸缩之扩容

集群伸缩 Redis 集群提供了灵活的节点扩容和收缩方案&#xff0c;当有新节点加入时&#xff0c;需要把一部分数据迁移到新节点来达到集群的负载均衡&#xff1b;当旧节点退出时&#xff0c;需要把其上的数据迁移到其他节点上&#xff0c;确保该节点上的数据能够被正常访问。从…

ext4 extent详解3之内核源码流程讲解

本文在前两篇《ext4 extent详解1之示意图演示》和《ext4 extent详解2之内核源码详解》讲解ext4 extent 文章的基础上&#xff0c;本文从内核源码、实例演示等角度详细介绍ext4 extent B树的形成过程&#xff0c;希望看过本文的读者能理解ext4 extent B树的工作原理。 1 &#…

6.3 返回类型和return语句

文章目录无返回值函数有返回值函数值是如何被返回的不要返回局部对象的引用或指针引用返回左值列表初始化返回值主函数main的返回值递归返回数组指针声明一个返回数组指针的函数使用尾置返回类型使用decltypereturn语句终止当前正在执行的函数并将控制权返回到调用该函数的地方…

2022年终总结:点滴积累让我不再迷茫

今年是开始写作的第二年&#xff0c;如果说第一年是起步的话&#xff0c;今年就是开始有了一些小收获了&#xff0c;通过点滴积累让我知道积累的充实感&#xff0c;通过一点一点粉丝或阅读量的积累&#xff0c;增加写作的自信。 今年的收获 首先看一下今年的阅读量和粉丝量: …

cheunghonghui的【22年度总结】

cheunghonghui的【22年度总结】 好久好久没写博客了&#xff0c;看了下后台&#xff0c;上一次发表博客已经是一年半之前&#xff0c;趁着年底&#xff0c;抓紧时间写&#xff08;水&#xff09;一篇不然就要断更了。 【年度工作总结】 1、迭代了未知bug 2、修复了已知bug …

迎接2023,他真的想说“新年快乐”

&#x1f60a;你好&#xff0c;我是小航&#xff0c;一个正在变秃、变强的文艺倾年。 &#x1f514;2023年快要到来啦&#xff0c;再此祝大家诸事顺遂&#xff0c;所见所盼皆如愿。 &#x1f514;本文讲解如何使用Java演奏一首歌曲&#xff0c;一起卷起来叭&#xff01; 众所周…

Faster RCNN网络源码解读(Ⅶ) --- RPN网络代码解析(中)RegionProposalNetwork类解析

目录 一、代码作用&#xff08;rpn_function.py&#xff09; 二、代码解析 2.1 RegionProposalNetwork类 2.1.1 初始化函数__init__ 2.1.2 正向传播过程forward 2.1.3 concat_box_prediction_layers函数 2.1.4 permute_and_flatten 2.1.5 filter_proposals 2.1.6 _…

2022 许些遗憾 年终总结

目录回首过去展望未来验收 2022年任务清单 ---------------------------》 2023年 flag2023 展望回首过去 此刻&#xff0c;想想这一年&#xff0c;口罩&#xff0c;38.5℃&#xff0c;艰难时刻&#xff0c;终究在2022最后十天被确诊了“阳”&#xff0c;没有备任何药&#xff…

Linux系列——Linux操作系统安装及服务控制(1)

作者简介&#xff1a;一名在校云计算网络运维学生、每天分享网络运维的学习经验、和学习笔记。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.Linux介绍 1.Linux是什么&#xff1f; 2.Linux系统的优点 …

ArcGIS基础实验操作100例--实验31纠正栅格坐标

本实验专栏参考自汤国安教授《地理信息系统基础实验操作100例》一书 实验平台&#xff1a;ArcGIS 10.6 实验数据&#xff1a;请访问实验1&#xff08;传送门&#xff09; 高级编辑篇--实验31 纠正栅格坐标 目录 一、实验背景 二、实验数据 三、实验步骤 &#xff08;1&…

2023新年祝福代码[css动画特效]

目录 前言 一、jQuery之家 二、2023新年祝福页面 2.1 我的博客和祝福语 2.2 我的博客头像和动态烟花 ​编辑 2.3 背景为动图 三、完整效果图 总结 前言 心态还需努力呀在这里祝大家新的一年里愿望都能实现。2022年已经过去&#xff0c;2022年的遗憾、不开心&#xff…

Spring学习笔记(1)

Spring系统架构 Spring Framework是Spring生态圈中最基础的项目&#xff0c;是其他项目的根基。 Spring Framework系统架构 学习线路 核心概念 IoC( Inversion of Control )控制反转 使用对象时&#xff0c;由主动new产生对象转换为由外部提供对象&#xff0c;此过程中对象…

DoIP协议从入门到精通—Alive check

惯例,为避免自己成为高知识低文化的汉子,分享一段喜欢的文字: 一、Socket 概念 在DoIP(Diagnostic on IP)概念中,通信的核心是Socket(套接字,实际通信的载体),是车载以太网在诊断范畴进行通信的句柄,Socket是支持TCP/IP协议的网络通信的基本操作单元。对于Socket: …

python多进程的理解 multiprocessing Process join run

最近看了下多进程。 一种接近底层的实现方法是使用 os.fork()方法&#xff0c;fork出子进程。但是这样做事有局限性的。比如windows的os模块里面没有 fork() 方法。 windows&#xff1a; 。linux&#xff1a; 另外还有一个模块&#xff1a;subprocess。这个没整过&#xff0c…

Canvas学习笔记 | 图片操作

图片素材 本篇文章的示例采用下图进行图片操作演示。 图片原始尺寸为&#xff1a;640px * 640px。 绘制图片 在Canvas中&#xff0c;我们使用drawImage()方法绘制图片。drawImage()方法有如下3种调用方式&#xff1a; 1.drawImage(image, dx, dy) 2.drawImage(image, dx, d…

【Android】带你细看Android input系统中ANR的机制

“本文基于Android13源码&#xff0c;分析Input系统的Anr实现原理“ 在文章之前&#xff0c;先提几个问题&#xff1a; 如果在activity任意周期&#xff08;onCreate,onResume等&#xff09;&#xff0c;同步执行耗时超过5s&#xff08;ANR时间&#xff09;的任务&#xff0c;…

JavaWeb06 AJAX 黑马用Axios实现用户名已存在问题? JSON Vue Element

01-AJAX-概述-替换JSP 02-AJAX-快速入门 03-案例-验证用户是否存在 04-Axios-基本使用&请求方式别名(可读性不强) 练习:用Axios替换AJAX实现用户名是否存在功能 就把原来的.html 2.2步换成下面的响应代码即可 为啥就是不行呢????? 05-JSON-概述和基础语法 06-JSON-…

并发编程——4.共享模型之内存

目录4.共享模型之内存4.1.Java 内存模型4.2.可见性4.2.1.退不出的循环4.2.2.解决办法4.2.3.可见性 vs 原子性4.3.终止模式之两阶段终止模式4.3.1.错误思路4.3.2.两阶段终止模式4.4.同步模式之 Balking4.4.1.定义4.4.2.实现4.5.有序性4.5.1.指令级并行原理4.5.2.案例4.6.原理之 …

LVS详解

一、负载均衡&#xff1a;必不可少的基础手段 1.1 找更多的牛来拉车吧 当前大多数的互联网系统都使用了服务器集群技术&#xff0c;集群即将相同服务部署在多台服务器上构成一个集群整体对外提供服务&#xff0c;这些集群可以是Web应用服务器集群&#xff0c;也可以是数据库服务…

新冠“照妖镜”,体质弱点现原形。你是啥症状?2023年,请好好善待你的身体!

新冠“照妖镜”&#xff0c;体质弱点现原形。你是啥症状&#xff1f; 阳性之后的不同症状&#xff0c;是我们身体发出的【预警信号】。 病毒进入时&#xff0c;最先攻击我们自身最薄弱的地方。 2023年&#xff0c;请好好【善待】你的身体&#xff01; 症状1 、头疼 出现头痛…