爬虫补环境jsdom、proxy、Selenium案例:某条

声明:
该文章为学习使用,严禁用于商业用途和非法用途,违者后果自负,由此产生的一切后果均与作者无关

一、简介

爬虫逆向补环境的目的是为了模拟正常用户的行为,使爬虫看起来更像是一个真实的用户在浏览网站。这样可以减少被网站封禁或限制访问的风险,提高爬取成功率。同时,合理的环境补充也有助于保护爬虫的隐私和安全,避免被恶意攻击或追踪。
由于浏览器和node的差别,很多网站会根据这些差别做一些校验,会导致浏览器的js代码在node没有办法执行,js代码会根据浏览器的这些属性来判断你是不是在真正的浏览器执行的代码,要不是正确的浏览器环境则不会返回正确的数据信息,拿到代码在node里面执行、经常看到这一类型的错误,提示xxx未定义,其实这一块就是浏览器对象的一些特征

二、找出网站加密位置,并扣出代码
  1. js运行 atob(‘aHR0cHM6Ly93d3cudG91dGlhby5jb20v’) 拿到网址,F12打开调试工具,点击推荐发送请求,找到 pc/list/feed 请求,鼠标右击请求找到Copy>Copy as cUrl(cmd)
  2. 打开网站:https://spidertools.cn/#/curl2Request,把拷贝好的curl转成python代码,新建 jrtt.py,把代码复制到该文件
    在这里插入图片描述
  3. 关键字_signature搜索,会发现有_signature赋值的地方
    在这里插入图片描述
  4. 右击该文件,选择在source中打开
    在这里插入图片描述
  5. 在该文件内 Ctrl+F 搜索_signature,会发现有两个赋值的地方全部打上断点
    在这里插入图片描述
    在这里插入图片描述
  6. 点击推荐重新发送请求,会发现断点进入 var n = I(F.getUri(e), e),鼠标悬浮到 I 上点击蓝色部分快速找到该方法,会发现一个 I(e, t) 方法,在该方法内部打断点
    在这里插入图片描述
    在这里插入图片描述
  7. 点击跳过断点,会进入该断点,分析代码会发现该代码return出去的是 a.call(n, o),而a=n.sign,n = window.byted_acrawler,o则是请求地址加上参数的一串字符,鼠标悬浮到 window.byted_acrawler 找到 sign方法,点击蓝色部分快速找到该方法,分析代码会发现该函数是jsvmp实现的,jsvmp是js虚拟机保护方案
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  8. 新建jrtt.js,把代码全部拷贝到该文件,再把 o 在控制台输出,拷贝到jrtt.js文件
    在这里插入图片描述
    在这里插入图片描述
三、打断点补环境
  1. 运行jrtt.js,会发现报 window 错误,window是浏览器中的,node环境不存在,在代码顶部补上window:window = global
    在这里插入图片描述
    在这里插入图片描述
  2. 运行jrtt.js,会报 sign 错误,这是因为刚才的sign是声明在 window.byted_acrawler 中,而现在的window中没有byted_acrawler,补上byted_acrawler:
    在这里插入图片描述
    在这里插入图片描述
  3. 运行jrtt.js,会报referrer的错误,在source中的加密文件,搜索 S[R] = S[R][A],会找到该代码,在该代码处打个日志断点,在日志断点处输出 S[R]、A、S[R]A
    在这里插入图片描述
    在这里插入图片描述
  4. 取消之前所有的断点,除了刚才的日志断点,刷新网页,会发现控制台中打印很多日志,这些就是刚才的日志断点生成的,控制台搜索referrer,会发现是document下的referrer,且值是一个空字符串,在代码顶部补上referrer
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  5. 运行jrtt.js文件 sign 错误,找代码会发现 “undefined” != typeof exports ? exports : void 0,这是环境检测 exports 是node环境的,把代码修改为 “undefined” == typeof exports
    在这里插入图片描述
  6. 运行jrtt.js文件会报 href 错误,同 referrer 一样,在控制台搜索 href,会发现 href 是 location 下的,在代码顶部补上该代码
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  7. 运行jrtt.js文件会报 length 错误,因太多对象有length,所以length不能像href、referrer 一样直接再浏览器控制台搜索,找到拷贝下的加密代码,搜索 S[R] = S[R][A],找到对应位置添加 console.log(A)
    在这里插入图片描述
    在这里插入图片描述
  8. 运行jrtt.js文件,会发现报错length的对象是protocol,同href、referrer,一样在控制台搜索protocol,会发现 protocol 是 location 下的,在代码顶部补上该代码
    在这里插入图片描述
    在这里插入图片描述
  9. 运行jrtt.js文件,会报userAgent的错误,在控制台搜索userAgent,会发现userAgent是navigator中的,在顶部补上该代码
    在这里插入图片描述
    在这里插入图片描述
  10. 再次运行jrtt.js文件,会发现已经没有报错,参数加密成功,直到现在补了 windows、href、protocol、userAgent这些
    在这里插入图片描述
  11. 验证加密结果:修改jjtt.py,并运行,数据获取成功
    在这里插入图片描述
    在这里插入图片描述
四、吐环境脚本,检测环境

使用Proxy对目标环境进行拦截,检测缺少的环境,Proxy对象由两个部分组成:target、handler
handler:是一个对象,声明了代理target的指定行为,支持的拦截操作,一共13种:

  1. get(target,propKey,receiver):拦截对象属性的读取。
  • target: 目标对象
  • propKey: 被获取的属性名。
  • receiver: Proxy 或者继承 Proxy 的对象
  1. set(target,propKey,value,receiver):拦截对象属性的设置,返回一个布尔值(修改成功)。
  • target: 目标对象
  • propKey: 被获取的属性名。
  • value: 新属性值。
  • receiver: Proxy 或者继承 Proxy 的对象
  1. 新建jsProxy.js,放入以下代码,代码可通用,需要扩展的可在该代码基础上扩展
// 代理器封装
function getEnv(proxy_array) {for(var i=0; i<proxy_array.length; i++){handler = `{\nget: function(target, property, receiver) {\nconsole.log('方法:get','    对象:${proxy_array[i]}','    属性:',property,'    属性类型:',typeof property,'    属性值类型:',typeof target[property]);return target[property];},set: function(target, property, value, receiver){\nconsole.log('方法:set','    对象:${proxy_array[i]}','    属性:',property,'    属性类型:',typeof property,'    属性值类型:',typeof target[property]);return Reflect.set(...arguments);}}`;eval(`try{\n${proxy_array[i]};\n${proxy_array[i]} = new Proxy(${proxy_array[i]},${handler});}catch(e){\n${proxy_array[i]}={};\n${proxy_array[i]} = new Proxy(${proxy_array[i]},${handler});}   `)}
}// proxy_array = ['window', 'document', 'location', 'navigator', 'history','screen','target' ]
// getEnv(proxy_array)module.exports = getEnv
  1. 修改jrtt.js,运行jrtt.js,会发现有很多undefined的,这些就是需要补的值,由刚才的断点不环境得知sessionStorage、localStorage、cookie等是不需要补的,所以如果不知道需要补哪些环境,就先补报错的,报错的补完,先验证下,如果验证不通过在补其他的
    在这里插入图片描述
    在这里插入图片描述
  2. 由刚才的报错得知location下的herf获取时值时undefined,所以先补href,直接在控制台输出location.href值补上
    在这里插入图片描述
  3. 重复步骤5,直到没有报错再去验证结果,运行jjtt.py后会发现,虽然没补referrer,但是数据依然获取成功,那是因为referrer是空值,已经在代理中把它之前的值返回了
    在这里插入图片描述
    在这里插入图片描述
五、Selenium补环境

selenium就是一个真实的浏览器环境,可以把扣下来的代码直接用Selenium来进行访问

  1. 新建jrtt.html,把之前扣下的代码拷贝到script下,因为是在浏览器下运行的,所以把之前检验环境的 “undefined” != typeof exports ? exports 还原
    在这里插入图片描述
    在这里插入图片描述

  2. 浏览器打开该html,验证window.byted_acrawler.sign会发现加密成功
    在这里插入图片描述

  3. 新建seleniumJrtt.py,如果运行出错,先检查下自己浏览器和谷歌驱动版本

import os
from selenium import webdriverPRO_DIR = os.path.dirname(os.path.abspath(__file__))
def driver_sig(html_file):option = webdriver.ChromeOptions()option.add_argument('--disable-blink-features=AutomationControlled')option.add_argument('headless')driver = webdriver.Chrome(options=option)driver.get(PRO_DIR +'\\'+ html_file)return driverhtml_file = 'jrtt.html'
driv = driver_sig(html_file)js_code = '''
return window.byted_acrawler.sign(arguments[0]);
'''par = {"url": "https://www.toutiao.com/api/pc/list/feed?channel_id=0&min_behot_time=1700905532&offset=0&refresh_count=7&category=pc_profile_recommend&aid=24&app_name=toutiao_web"
}result = driv.execute_script(js_code,par)print(result)
六、jsdome补环境

在这里插入图片描述

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

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

相关文章

前端基础知识整理汇总(下)

react 生命周期 React v16.0前的生命周期 初始化(initialization)阶段 此阶段只有一个生命周期方法&#xff1a;constructor。 constructor() 用来做一些组件的初始化工作&#xff0c;如定义this.state的初始内容。如果不初始化 state 或不进行方法绑定&#xff0c;则不需…

编程艺术之Unix哲学

Unix 哲学不算是一种正规设计方法&#xff0c;它并不打算从计算机科学的理论高度来产生理论上完美的软件。那些毫无动力、松松垮垮而且薪水微薄的程序员们&#xff0c;能在短短期限内&#xff0c;如神灵附体般开发出稳定而新颖的软件——这只不过是经理人永远的梦呓罢了。 1 Un…

isis实验

根据要求制作大概&#xff1a; 使用isis配置路由器&#xff1a; 配置好物理接口地址后配置isis 为实现r1访问r5的环回走r6,需要在r6上制作路由泄露&#xff1a; 在r5上产生r1的路由明细&#xff1a; 全网可达&#xff1a;

华为 HarmonyOS 页面跳转

HarmonyOS 页面跳转 1.新建页面2.添加跳转方法3.实现跳转效果 1.新建页面 我们新建2个页面(page)&#xff0c;一个Hello World页面&#xff0c;一个Hello HarmonyOS页面&#xff0c;注意修改红色框内容&#xff0c;保持一致 2.添加跳转方法 导入导入router模块&#xff0c;页…

Rust-内存安全

堆和栈 一个进程在执行的时候&#xff0c;它所占用的内存的虚拟地址空间一般被分割成好几个区域&#xff0c;我们称为“段”(Segment)。常见的几个段如下。 代码段。编译后的机器码存在的区域。一般这个段是只读的。bss段。存放未初始化的全局变量和静态变量的区域。数据段。…

MATLAB Deep learning

文章目录 Chapter 1: Machine Learning存在的问题过拟合Overfitting解决过拟合 regularization and validationregularization 正则化validation 验证 机器学习的类型有监督学习分类Classification回归Regression 无监督学习聚类 强化学习 Chapter 2: Neural NetworkChapter 3:…

(BUUCTF)ycb_2020_easy_heap (glibc2.31的off-by-null + orw)

文章目录 前置知识整体思路高版本的off-by-nullorw exp 前置知识 未初始化内存导致的地址泄露 高版本下的off-by-null利用 glibc2.31下的orw做法 整体思路 非常综合的一道题目&#xff0c;和ciscn之前做过的一道silverwolf很相似&#xff0c;本道题目的glibc2.31的环境也让…

Django教程第6章 | web开发实战-文件上传(导入文件、上传图片)

专栏系列&#xff1a;Django学习教程 导入文件 目标&#xff1a;导入部门清单excel&#xff0c;解析excel数据存储到数据库。 1.准备要导入的excel文件 2.编写模板HTML <div class"panel panel-default"><!-- Default panel contents --><div class…

Embedding Watermarks into Deep Neural Networks

将水印嵌入深度神经网络 ABSTRACT 最近在深度神经网络领域取得了显著的进展。分享深度神经网络的训练模型对于这些系统的快速研究课并发进展至关重要。与此同时&#xff0c;保护共享训练模型的权利也变得十分必要。为此我们提议使用数字水印技术来保护知识产权&#xff0c;并…

vue3-模板引用

//1.调用ref函数 -> ref对象 const h1Ref ref(null) const comRef ref(null) //组件挂载完毕之后才能获取 onMounted(()>{console.log(h1Ref.value);console.log(comRef.value); })<div class"father"><!-- 通过ref标识绑定ref对象 --><h2 re…

【工具栏】SequenceDiagram插件的使用(根据代码生成时序图)

1. 安装 2.使用 进入代码页面&#xff0c;点击鼠标右键 选择方法 根据方法中的代码生成时序图

2024年【山东省安全员C证】考试及山东省安全员C证复审考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 山东省安全员C证考试是安全生产模拟考试一点通总题库中生成的一套山东省安全员C证复审考试&#xff0c;安全生产模拟考试一点通上山东省安全员C证作业手机同步练习。2024年【山东省安全员C证】考试及山东省安全员C证复…

docker部署私人云盘

目录 1.安装 2.登陆 1.安装 mkdir -p /opt/alist docker run -d --restartalways -v /opt/alist:/opt/alist/data -p 5244:5244 --name"alist" xhofe/alist:latest 2.登陆 ip:5224 默认账户admin 密码在日志中

test-04-test case generate 测试用例生成 tcases 快速开始

拓展阅读 junit5 系列 基于 junit5 实现 junitperf 源码分析 Auto generate mock data for java test.(便于 Java 测试自动生成对象信息) Junit performance rely on junit5 and jdk8.(java 性能测试框架。性能测试。压测。测试报告生成。) 自动生成测试用例 入门指南 关于…

js中关于字符串的创建和判断类型

文章目录 创建方法判断类型的技巧区分1、typeof2、instanceof 共点1、Object.prototype.toString.call2、库函数 参考链接&#xff1a;JS字符串的创建和常用方法 如何判断JS中一个变量是 string 类型 创建方法 字符串有着两种的创建方法&#xff0c;一个是使用构造函数&#x…

openssl3.2 - 官方demo学习 - server-arg.c

文章目录 openssl3.2 - 官方demo学习 - server-arg.c概述笔记备注END openssl3.2 - 官方demo学习 - server-arg.c 概述 TLS服务器, 等客户端来连接; 如果客户端断开了, 通过释放bio来释放客户端socket, 然后继续通过bio读来aceept. 笔记 对于开源工程, 不可能有作者那么熟悉…

HCIA-Datacom题库(自己整理分类的)_09_Telnet协议【14道题】

一、单选 1.某公司网络管理员希望能够远程管理分支机构的网络设备&#xff0c;则下面哪个协议会被用到&#xff1f; RSTP CIDR Telnet VLSM 2.以下哪种远程登录方式最安全&#xff1f; Telnet Stelnet v100 Stelnet v2 Stelnet v1 解析&#xff1a; Telnet 明文传输…

中职组安全-win20230217-环境-解析

*任务说明&#xff1a; 仅能获取win20230217的IP地址 用户名&#xff1a;test&#xff0c;密码&#xff1a;123456 访问服务器主机,找到主机中管理员名称,将管理员名称作为Flag值提交&#xff1b; john 访问服务器主机,找到主机中补丁信息,将补丁编号作为Flag值提交&#xff…

【数字人】9、DiffTalk | 使用扩散模型基于 audio-driven+对应人物视频 合成说话头(CVPR2023)

论文&#xff1a;DiffTalk: Crafting Diffusion Models for Generalized Audio-Driven Portraits Animation 代码&#xff1a;https://sstzal.github.io/DiffTalk/ 出处&#xff1a;CVPR2023 特点&#xff1a;需要音频对应人物的视频来合成新的说话头视频&#xff0c;嘴部抖…

《Git学习笔记:Git入门 常用命令》

1. Git概述 1.1 什么是Git&#xff1f; Git是一个分布式版本控制工具&#xff0c;主要用于管理开发过程中的源代码文件&#xff08;Java类、xml文件、html页面等&#xff09;&#xff0c;在软件开发过程中被广泛使用。 其它的版本控制工具 SVNCVSVSS 1.2 学完Git之后能做…