爬虫补环境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 = `{\n
            get: function(target, property, receiver) {\n
                   console.log('方法:get','    对象:${proxy_array[i]}','    属性:',property,'    属性类型:',typeof property,'    属性值类型:',typeof target[property]);
                   return target[property];
            },
            set: function(target, property, value, receiver){\n
                    console.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 webdriver

PRO_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 driver

html_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补环境

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

《最新出炉》系列入门篇-Python+Playwright自动化测试-9-页面(page)

1.简介 通过前边的讲解和学习&#xff0c;细心认真地小伙伴或者童鞋们可能发现在Playwright中&#xff0c;没有Element这个概念&#xff0c;只有Page的概念&#xff0c;Page不仅仅指的是某个页面&#xff0c;例如页面间的跳转等&#xff0c;还包含了所有元素、事件的概念&#…

大数据仓库开发规范示例

大数据仓库开发规范示例 一、前提概要二、数仓分层原则及定义2.1 数仓分层原则2.2 数仓分层定义 三、数仓公共开发规范3.1 分层调用规范3.2 数据类型规范3.3 数据冗余规范3.4 NULL字段处理规范3.5 公共字段规范3.6 数据表处理规范3.7 事实表划分规范 四、数仓各层开发规范4.1 分…

Linux配置JAR包为服务实现自启动

一、实现bash脚本 1.1 绘图工具 绘图需安装idea的插件plantUML-Integration 只需要上图一个就可以&#xff0c;别的也不需要装。 启动服务的逻辑如下 关闭服务的逻辑如下 1.2 逻辑实现 在/root路径下创建entrance文件&#xff0c;实现逻辑如下 #!/usr/bin/env bash # 2>…

【120版本】最新谷歌浏览器驱动下载地址

在使用selenium时可能会遇到谷歌浏览器和谷歌驱动器版本不一致的问题&#xff0c;并且国内可以搜到的谷歌浏览器下载地址里面最新的驱动器只有114版本的&#xff0c;但目前谷歌浏览器最新版本是120。所以这里记录下最新版本120谷歌驱动器下载地址&#xff1a; Chrome for Test…

spark中Rdd依赖和SparkSQL介绍--学习笔记

1&#xff0c;RDD的依赖 1.1概念 rdd的特性之一 相邻rdd之间存在依赖关系&#xff08;因果关系&#xff09; 窄依赖 每个父RDD的一个Partition最多被子RDD的一个Partition所使用 父rdd和子rdd的分区是一对一&#xff08;多对一&#xff09; 触发窄依赖的算子 map()&…

强化学习应用(七):基于Q-learning的无人机物流路径规划研究(提供Python代码)

一、Q-learning简介 Q-learning是一种强化学习算法&#xff0c;用于解决基于马尔可夫决策过程&#xff08;MDP&#xff09;的问题。它通过学习一个价值函数来指导智能体在环境中做出决策&#xff0c;以最大化累积奖励。 Q-learning算法的核心思想是通过不断更新一个称为Q值的…

【每日小bug】mybatis plus id注解错误导致的问题

插入数据 id不为自增 指定了主键&#xff0c;没有指定自增。会导致出现 修改如上 报错 Data truncation: Out of range value for column ‘id’ at row 1 数据库是bigint&#xff0c;java中是Integer。 修改如上

GCC工具源码编译

文章目录 背景一、下载源码二、编译前依赖准备2.1 相关工具依赖2.2 相关lib&#xff08;gmp/ mpfr /mpc&#xff09;依赖2.2.1 lib源码下载2.2.2 lib源码编译 三、编译GCC3.1 编译3.2 链接 四、报错处理 背景 日常可能涉及到系统里自带GCC版本与被编译源码存在不兼容&#xff…

1 - Spring 基本介绍

官网&#xff1a;https://spring.io/ Spring 是一个可以管理整合其他框架的框架 1. IOC 开发模式 程序不再负责对象的创建&#xff0c;而是直接使用ioc容器的对象来完成相关的业务逻辑 1.1 控制反转实现思想 1&#xff09;Spring 根据配置文件 xml/注解&#xff0c;创建对象…

AR HUD全面「上新」

AR HUD赛道正在迎来新的时代。 上周&#xff0c;蔚来ET9正式发布亮相&#xff0c;新车定位为D级行政旗舰轿车&#xff0c;其中&#xff0c;在智能座舱交互层面&#xff0c;继理想L系列、长安深蓝S7之后&#xff0c;也首次取消仪表盘&#xff0c;取而代之的是业内首个全焦段AR H…

9.5.1 函数模板特化

函数模板 有了泛化版本比较函数&#xff0c;我们可以比较两个整数&#xff0c;两个字符&#xff0c;两个指针 6~10行&#xff0c;是一个函数模板 13~16行&#xff0c;都可以得到正常结果 22行&#xff0c;得到的结果是&#xff0c;"A001" < "A000", …

亚马逊时尚如何运用人工智能帮助您找到合适的尺码

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

命令行(无图形界面)登录dlut-lingshui

1 登录原理 利用python的requests库向校园网认证服务器发送认证请求。 2 登录步骤 获取校园网认证界面的用户名和密码。用户名是自己学号&#xff1b;密码由网页加密&#xff0c;需要一台有图形界面的电脑辅助获取&#xff0c;获取方法见下一节。把获取到的用户名和密码填入…

【AIGC】IP-Adapter:文本兼容图像提示适配器,用于文本到图像扩散模型

前言 IPAdapter能够通过图像给Stable Diffusion模型以内容提示&#xff0c;让其生成参考该图像画风&#xff0c;可以免去Lora的训练&#xff0c;达到参考画风人物的生成效果。 摘要 通过文本提示词生成的图像&#xff0c;往往需要设置复杂的提示词&#xff0c;通常设计提示词变…

【JavaSE语法】图书管理系统实现详解

图片出处&#xff1a;The worlds biggest drone photo and video sharing platform | SkyPixel.com 导言 在学完JavaSE语法后&#xff0c;我们就可以去尝试写一个简单的图书管理系统来进一步提升我们面对对象编程的思想。在该系统中会涉及到数组&#xff0c;接口&#xff0c;封…

案例118:基于微信小程序的电影院订票选座系统设计及实现

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;SSM JDK版本&#xff1a;JDK1.8 数据库&#xff1a;mysql 5.7 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.5.4 小程序框架&#xff1a;uniapp 小程序开发软件&#xff1a;HBuilder X 小程序…

安卓手机变iOS!

Launcher iOS 16 - 安卓手机秒变iOS Launcher iOS 16 是一款iOS启动器&#xff0c;可以将安卓手机桌面变成iOS样子&#xff0c;还有iOS的开机动画和景深效果&#xff01; 下载链接&#xff1a;【Launcher iOS 16】 ​

python flask学生管理系统

预览 前端 jquery css html bootstrap: 4.x 后端 python: 3.6.x flask: 2.0.x 数据库 mysql: 5.7 学生管理模块 登录、退出查看个人信息、修改个人信息成绩查询查看已选课程选课、取消选课搜索课程课程列表分页功能 教师模块 登录、退出查看个人信息、修改个人信息录入…

为什么选择Go语言编写网络应用程序

关注公众号【爱发白日梦的后端】分享技术干货、读书笔记、开源项目、实战经验、高效开发工具等&#xff0c;您的关注将是我的更新动力&#xff01; 作为一名后端开发者&#xff0c;你一定对选择合适的编程语言来编写网络应用程序非常重视。在众多的编程语言中&#xff0c;Go语言…

Vue keep-alive的使用和原理解析

✨ 专栏介绍 在当今Web开发领域中&#xff0c;构建交互性强、可复用且易于维护的用户界面是至关重要的。而Vue.js作为一款现代化且流行的JavaScript框架&#xff0c;正是为了满足这些需求而诞生。它采用了MVVM架构模式&#xff0c;并通过数据驱动和组件化的方式&#xff0c;使…