【JS逆向基础】WEB自动化

前言:随着互联网的发展,前端技术也在不断变化,数据的加载方式也不再是单纯的服务端渲染了。现在你可以看到很多网站的数据可能都是通过接口的形式传输的,或者即使不是接口那也是一些 JSON 的数据,然后经过 JavaScript 渲染得出来的。

这时,如果你还用 requests 来爬取内容,那就不管用了。因为requests 爬取下来的只能是服务器端网页的源码,这和浏览器渲染以后的页面内容是不一样的。因为,真正的数据是经过 JavaScript 执行后,渲染出来的,数据来源可能是 Aiax,也可能是页面里的某些 Data,或者是一些 ifame 页面等。不过,大多数情况下极有可能是 Aiax 接口获取的。

所以,很多情况我们需要分析 Aiax请求,分析这些接口的调用方式,通过抓包工具或者浏览器的"开发者工具”,找到数据的请求链接,然后再用程序来模拟。但是,抓包分析流的方式,也存在一定的缺点。因为有些接口带着加密参数,比如 token、sign 等等,模拟难度较大;

那有没有一种简单粗暴的方法,这时 Puppeteer、Pyppeteer、Selenium、Splash 等自动化框架出现了。使用这些框架获取HTML源码,这样我们爬取到的源代码就是JavaScript 渲染以后的真正的网页代码,数据自然就好提取了。同时,也就绕过分析 Ajax 和-些 JavaScript 逻辑的过程。这种方式就做到了可见即可爬,难度也不大,同时适合大批量的采集。

Selenium,作为一款知名的Web自动化测试框架,支持大部分主流浏览器,提供了功能丰富的API接口,常常被我们用作爬虫工具来使用。然而selenium的缺点也很明显,比如速度太慢、对版本配置要求严苛,最麻烦是经常要更新对应的驱动


1,selenium

1.1 安装

由于sleenium4.1.0需要python3.7以上方可支持,请注意自己的python版本。

方式1:pip安装

Python3.x安装后就默认就会有pip (pip.exe默认在python的Scripts路径下),打开 cmd,使用pip安装。

pip install selenium

首次安装会有进度条,而且装出来是多个包(依赖于其他第三方库)。如果安装慢(默认连接官网),可以指定国内源。

pip install selenium -i Simple Index

方式2:Pycharm安装

Pycharm-File-Setting-Project:xxxx-Python Interpreter,点击+号

下载浏览器驱动

chrome驱动地址:

http://chromedriver.storage.googleapis.com/index.html

==========================

安装对应驱动

Microsoft Edge WebDriver | Microsoft Edge Developer

检查浏览器版本,下载对应版本驱动

1.2 quick start

selenium最初是一个自动化测试工具,而爬虫中使用它主要是为了解决rpquests无法直接执行javaScript代码的问题 selenium本质是通过驱动浏览器,完全模拟浏览器的操作,比如跳转、输入、点击、下拉等,来拿到网页渲染之后的结果,可支持多种浏览器安装pip包

import time
from selenium import webdriver   # 按照什么方式查找 By.ID
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys # 键盘按键操作
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait ## edge_driver_path = 'D:\python12'
edge_data = webdriver.Edge()
edge_data.get("https://www.baidu.com")
input_tag = edge_data.find_element(By.ID, 'kw') #百度的搜索输入框ID是kwinput_tag.send_keys('hellokitty')
time.sleep(2)# 关闭浏览器
edge_data.quit()
​

1.2.1 元素定位

方式1

el = driver.find element by xxx(value)

方式2:推荐

from selenium.webdriver.common.by import By 
driver.find element(By.xxx,value) 
driver.find elements(Byxx,value)# 返回列表

八种方式:

id
nawe
class
tag
link
partial
xpath
Css

1.2.2 元素操作(节点交互)

Selenium可以驱动浏览器来执行一些操作,也就是说可以让浏览器模拟执行一些动作。比较常见的用法有:输入文字时用 send _keys()方法,清空文字时用clear()方法,点击按钮时用 click()方法。示例如下:

find_element方法仅仅能够获取元素对象,接下来就可以对元素执行以下操作 从定位到的元素中提取数据的方法

  • 从定位到的元素中获取数据

el.get_attribute(key)
el.text

获取key属性名对应的属性值

获取开闭标签之间的文本内容

  • 对定位到的元素的操作

el.click()  # 对元素执行点击操作
el.submit() # 对元素执行提交操作
el.clear()  # 清空可输入元素中的数据
el.send_keys(data) # 向可输入元素输入数据

1.2.3 动作链

在上面的实例中,一些交互动作都是针对某个节点执行的。比如,对于输入框,我们就调用它的输入文字和清空文字方法;对于按钮,就调用它的点击方法。其实,还有另外一些操作,它们没有特定的执行对象,比如鼠标拖曳、键盘按键等,这些动作用另一种方式来执行,那就是动作链。

比如,现在实现一个节点的拖曳操作,将某个节点从一处拖曳到另外一处,可以这样实现

from time import sleep
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import Bydriver = webdriver.Edge()
driver.implicitly_wait(10)
driver.maximize_window()
driver.get('http://sahitest.com/demo/dragDropMooTools.htm')dragger = driver.find_element(By.ID,'dragger')   # 被拖拽元素item1 = driver.find_element(By.XPATH,'//div[text()="item_1"]') #目标元素1
item2 = driver.find_element(By.XPATH,'//div[text()="item_2"]')# 目标2
item3 = driver.find_element(By.XPATH,'//div[text()="item_3"]')# 目标3
item4 = driver.find_element(By.XPATH,'//div[text()="item_4”]') #目标4
action = ActionChains(driver)
action.drag_and_drop(dragger,item1).perform()       #1.移动dragger到目标1
sleep(2)
action.click_and_hold(dragger).release(item2).perform() #2.效果与上句相同,也能起到移动效果
sleep(2)
action.click_and_hold(dragger).move_to_element(item3).release().perform() #3,效果与上两句相同,也能起到移动的效果
sleep(2)
action.click_and_hold(dragger).move_by_offset(800,0).release().perform()
sleep(2)
driver.quit()

1.2.4 执行JS

selenium并不是万能的,有时候页面上操作无法实现的,这时候就需要借助JS来完成了

当页面上的元素超过一屏后,想操作屏幕下方的元素,是不能直接定位到,会报元素不可见的。这时候需要借助滚动条来拖动屏幕,使被操作的元素显示在当前的屏幕上。滚动条是无法直接用定位工具来定位的。selenium里面也没有直接的方法去控制滚动条,这时候只能借助Js代码了,还好selenium提供了一个操作js的方法:execute_script(),可以直接执行js的脚本。代码如下:

import time
from selenium import webdriver
browser = webdriver.Chrome()
browser.get('https://www.jd.com/')
browser.execute_script('window.scrollTo(0,document.body.scrollHeight)')
time.sleep(3)

1.2.5 页面等待

为什么需要等待

如果网站采用了动态html技术,那么页面上的部分元素出现时间便不能确定,这个时候就可以设置一个等待时间,强制等待指定时间,等待结束之后进行元素定位,如果还是无法定位到则报错

页面等待的三种方法

  • 强制等待

也叫线程等待,通过线程休眠的方式完成的等待,如等待5秒: Thread sleep(5000),一般情况下不太使用强制等待,主要应用的场景在于不同系统交互的地方。

import time time.sleep(n)

阻塞等待设定的秒数之后再继续往下执行

  • 显式等待

也称为智能等待,针对指定元素定位指定等待时间,在指定时间范围内进行元素查找,找到元素则直接返回,如果在超时还没有找到元素,则抛出异常,显示等待是 selenium 当中比较灵活的一种等待方式,他的实现原理其实是通过 while 循环不停的尝试需要进行的操作。

from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# 每隔 0.5s 检查一次(默认就是 0.5s),最多等待 10 秒,否则报错。如果定位到元素则直接结束等待,如果在10秒结束之后仍未定位到元素则报错
chrome = webdriver.Edge()
# 发起请求
chrome.get('https://www.jd.com')
# 查找响应页面中的某个标签元素
img_s = chrome.find_elements(By.CLASS_NAME, "focus-item-img")
wait = WebDriverWait(chrome,10,0.5)
wait.until(EC.presence_of_element_located((By.ID, 'J goodsList')))
  • 隐式等待

隐式等待设置之后代码中的所有元素定位都会做隐式等待通过implicity_wait完成的延时等待,注意这种是针对全局设置的等待,如设置超时时间为10秒,使用了implicitly_wait后,如果第一次没有找到元素,会在10秒之内不断循环去找元素,如果超过10秒还没有找到,则抛出异常,隐式等待比较智能它可以通过全局配置,但是只能用于元素定位

driver.implicitly_wait(10) #在指定的n秒内每隔一段时间尝试定位元素,如果n秒结束还未被定位出来则报错

注意:

Selenium显示等待和隐式等待的区别

1、selenium的显示等待原理:显示等待,就是明确要等到某个元素的出现或者是某个元素的可点击等条件,等不到,就一直等,除非在规定的时间之内都没找到,就会跳出异常Exception

(简而言之,就是直到元素出现才去操作,如果超时则报异常)

2、selenium的隐式等待

原理:隐式等待,就是在创建driver时,为浏览器对象创建一个等待时间,这个方法是得不到某个元素就等待一段时间,直到拿到某个元素位置。

注意:

在使用隐式等待的时候,实际上浏览器会在你自己设定的时间内部断的刷新页面去寻找我们需要的元素

1.2.6 selenium的其他操作

  • 无头浏览器

我们已经基本了解了selenium的基本使用了,但是呢,不知各位有没有发现,每次打开浏览器的时间都比较长,这就比较耗时了.我们写的是爬虫程序.目的是数据,并不是想看网页.那能不能让浏览器在后台跑呢?答案是可以的

from selenium.webdriver import Chrome
from selenium.webdriver.chrome.options import Options
opt = Options()
opt.add_argument("--headless")
opt.add_argument('--disable-gpu')
opt.add_argument("--window-size=4000,1600") #设置窗口大小
web = Chrome(options=opt)
  • selenium处理cookie

# 通过driver.get_cookies()能够获取所有的cookie
dictCookies=driver.get_cookies()   #添加cookie
driver.add_cookie(dictCookies)     #删除-条cookie
driver.delete_cookie("CookieName")  #删除所有的cookie
driver.delete_all_cookies()
  • 页面前进和后退

driver.forward()  #前进
driver.back()     #后退学
driver.refresh()  #刷新
driver.close()    #关闭当前窗口

1.2.7 滑动验证案例

import time
from selenium import webdriver
from selenium.webdriver.common.by import By # 按照什么方式査找
from selenium.webdriver.support import expected conditions as EC
from selenium.webdriver.support.wait import webDriverWait    #等待页面加载某些元素
import cv2
from urllib import request
from selenium.webdriver.comon.action chains import Actionchains

2 ,pyppeteer

由于Selenium流行已久,现在稍微有点反爬的网站都会对selenium和webdriver进行识别,网站只需要在前端js添加一下判断脚本,很容易就可以判断出是真人访问还是webdriver。虽然也可以通过中间代理的方式进行js注入屏蔽webdriver检测,但是webdriver对浏览器的模拟操作(输入、点击等等)都会留下webdriver的标记,同样会被识别出来,要绕过这种检测,只有重新编译webdriver,麻烦自不必说,难度不是一般大。由于Selenium具有这些严重的缺点。pyppeteer成为了爬虫界的又一新星。相比于selenium具有异步加载、速度快、具备有界面/无界面模式、伪装性更强不易被识别为机器人,同时可以伪装手机平板等终端;虽然支持的浏览器比较单一,但在安装配置的便利性和运行效率方面都要远胜selenium。

  • pyppeteer的安装

pyppeteer无疑为防爬墙撕开了一道大口子,针对selenium的淘宝、美团、文书网等网站,目前可通过该库使用selenium的思路继续突破,毫不费劲。

介绍Pyppeteer之前先说一下Puppeteer,Puppeteer是谷歌出品的一款基于Node.js开发的一款工具,主要是用来操纵Chrome浏览器的 APl,通过Javascript代码来操纵Chrome浏览器,完成数据爬取、Web程序自动测试等任务。

pyppeteer是非官方 Python 版本的 Puppeteer 库,浏览器自动化库,由日本工程师开发

Puppeteer是 Google 基于 Node.js 开发的工具,调用 Chrome 的 API,通过 JavaScript代码来操纵 Chrome 完成一些操作,用于网络爬虫、Web 程序自动测试等。

pyppeteer 使用了 Python 异步协程库asyncio,可整合 Scrapy 进行分布式爬虫。

puppet 木偶,puppeteer 操纵木偶的人。

pip3 install pyppeteer

使用之前需要运行下这个代码

import pyppeteer.chromium_downloader
print('默认版本是:{}'.format(pyppeteer.__chromium_revision__))
print('可执行文件默认路径:{}'.format(pyppeteer.chromium_downloader.chromiumExecutable.get('win64')))
print('win64平台下载链接为:{}'.format(pyppeteer.chromium_downloader.downloadURLs.get('win64')))

查看电脑中间的可执行文件的默认的路径,如果没有需要建立相对应的文件夹,下面为下载路径

下载完成之后需要将对应的解压缩之后的文件夹放到上面的文件夹的目录下面

commondatastorage.googleapis.com/chromium-browser-snapshots/index.html?prefix=Win_x64/

  • pyppeteer滑动验证案例

from pyppeteer import launch
import random
import asyncio
import cv2
from urllib import requestasync def get_track():big = cv2.imread("bigimg.jpg",0)small = cv2.imread("smallimg.jpg",0)# print("cv2:",small)res = cv2.matchTemplate(big, small, cv2.TM_CCOEFF_NORMED)value = cv2.minMaxLoc(res)[2][0]print(value)#需要通过渲染比计算出实际的距离return value * 342 / 360async def main():browser = await launch({"headless": False,"args":["--window-size=1920,1080"],})#打开新的标签页page = await browser.newPage()# 设置界面大小一致await page.setViewport({"width":1920, "height":1080})#访问主页await page.goto("https://passport.jd.com/new/login.aspx")await page.type("#loginname","18438371807",{"c":random.randint(30,60)})await page.type("#nloginpwd", "abc10000610", {"delay":random.randint(30, 60)})await page.waitFor(2000)await page.click("div.login-btn")await page.waitFor(2000)# page.Jeval(selector,pageFunction)  # 定位元素,并调用js函数去执行big_img = await page.Jeval(".JDJRV-bigimg > img","el=>el.src")small_img = await page.Jeval(".JDJRV-smallimg > img", "el=>el.src")# 下载图片request.urlretrieve(big_img, 'bigimg.jpg')request.urlretrieve(small_img, 'smallimg.jpg')# 得到滑动的距离distance = int(await get_track())print("distance:", distance)# Pyppeteer 三种解析方式# Page.querySelector()  # 选择器# Page.querySelectorAll()# Page.xpath()   #xpath 表达式# 简写方式为:# Page.J(), Page.j](), and Page.Jx()el = await page.J("div.JDJRV-slide-btn")#获取元素的边界框box = await el.boundingBox()await page.hover("div.JDJRV-slide-btn")await page.mouse.down()# steps 是指分成几步来完威  steps越大,滑动速度越慢await page.mouse.move(box["x"] + distance + random.uniform(30,33), box["y"], {"steps":100})await page.waitFor(2000)await page.mouse.move(box["x"] + distance + 29, box["y"], {"steps": 100})await page.mouse.up()await page.waitFor(2000)if __name__ == "__main__":asyncio.get_event_loop().run_until_complete(main())

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

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

相关文章

大型旋转机械信号趋势分析算法模块

大型旋转机械信号趋势分析算法模块,作为信号处理算法工具箱的主要功能模块,可应用于各类关键机械部件(轴承、齿轮、转子等)的信号分析、故障探测、趋势劣化评估等,采用全Python语言,以B/S模式,通…

01背包专题4:小A点菜

题目背景 uim 神犇拿到了 uoi 的 ra(镭牌)后,立刻拉着基友小 A 到了一家……餐馆,很低端的那种。 uim 指着墙上的价目表(太低级了没有菜单),说:“随便点”。 题目描述 不过 uim …

探索SQLMesh中的Jinja宏:提升SQL查询的灵活性与复用性

在数据工程和数据分析领域,SQL是不可或缺的工具。随着项目复杂度的增加,如何高效地管理和复用SQL代码成为了一个重要课题。SQLMesh作为一款强大的工具,不仅支持标准的SQL语法,还引入了Jinja模板引擎的宏功能,极大地提升…

MySQL的深度分页如何优化?

大家好,我是锋哥。今天分享关于【MySQL的深度分页如何优化?】面试题。希望对大家有帮助; MySQL的深度分页如何优化? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 MySQL的深度分页在处理大数据量时可能会导致性能瓶颈,特别是在…

SpringBoot3集成Mybatis

文章目录 基础使用代码1. 创建Spring Boot 3项目并添加依赖2. 配置数据库连接3. 创建实体类4. 创建Mapper接口5. 创建Service层6. 创建Controller层7. 主应用类 踩坑记录1. 依赖版本不兼容2. Mapper接口扫描问题3. 数据库连接问题4. Java版本问题 心得体会 基础使用代码 1. 创…

汽车加气站操作工考试知识点总结

汽车加气站操作工考试知识点总结 加气站基本知识 了解加气站类型(CNG、LNG、LPG等)及其特点。 熟悉加气站的主要设备,如储气瓶组、压缩机、加气机、卸气柱、安全阀等。 掌握加气站工艺流程,包括卸气、储气、加压、加气等环节。…

88、合并两个有序数组

题目描述 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。 请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。 注意:最终,…

在ubuntu的docker上常用的docker命令

在 Ubuntu 系统上使用 Docker 时,以下是最常用的前 200 个 Docker 命令,并按类别进行分类。这些命令涵盖了 Docker 的基本操作、管理容器、镜像、网络、卷等方面的功能,适用于日常使用和高级管理任务。 1. 基本命令 这些是与 Docker 交互的基…

ICode国际青少年编程竞赛—Python—4级训练场—复杂嵌套循环

ICode国际青少年编程竞赛—Python—4级训练场—复杂嵌套循环 icode练习时遇到卡顿没有思路时怎么办,题目也很难找到不会的那道题~针对这个问题,我们开发了通过“步数”、“积木行数”来快速定位到你不会的题目~ 题目会持续更新…

交替序列长度的最大值

1、题目描述 给出n个正整数,你可以随意从中挑选一些数字组成 一段序列S,该序列满足以下两个条件: 1.奇偶交替排列:例如:"奇,偶,奇,偶,奇.…" 或者 "偶&a…

电机试验平台:功能架构与关键技术介绍

电机试验平台作为电机研发、生产和质量控制的核心设备,其设计与应用直接关系到电机性能测试的准确性和效率。随着工业自动化、新能源汽车等领域的快速发展,对电机性能的要求日益提高,电机试验平台的设计也需不断优化以适应多样化需求。以下从…

ubuntu修改时区和设置24小时格式时间

ubuntu修改时区和设置24小时格式时间 一、修改时区二、设置24小时格式时间endl 一、修改时区 使用timedatectl命令更改当前时区为东八区[rootubuntu24-16:~]# timedatectl list-timezones | grep -i shanghai Asia/Shanghai [rootubuntu24-16:~]# timedatectl set-timezone As…

【IP101】图像分割技术全解析:从传统算法到深度学习的进阶之路

图像分割详解 ✂️ 欢迎来到图像处理的"手术室"!在这里,我们将学习如何像外科医生一样精准地"切割"图像。让我们一起探索这个神奇的图像"手术"世界吧!🏥 目录 📑 1. 图像分割简介2. 阈…

URL混淆与权限绕过技术

一、漏洞原理 前后端路径解析逻辑不一致 后端框架(Spring/Shiro)自动处理特殊字符(../、//),但鉴权组件(如Filter)未规范化原始URI。 示例:/system/login/../admin被Filter误判为白…

Redis卸载重装教程

卸载 找到redis安装目录 cmd打开该目录,输入 redis-server --service-uninstall运行结果如下 最后再删除redis文件夹即可(如果显示该文件夹已在其他地方被打开而无法删除,可以重启一下电脑,就能正常删除啦) 安装R…

使用OpenCV 和 Dlib 实现人脸融合技术

文章目录 引言一、技术概述二、环境准备三、关键代码解析1. 人脸关键点定义2. 获取人脸掩模3. 计算仿射变换矩阵4. 检测并提取人脸关键点5. 颜色校正 四、完整流程五、效果展示六、总结 引言 本文将介绍如何使用Python、OpenCV和dlib库实现人脸融合技术,将一张人脸…

skywalking服务安装与启动

skywalking服务安装并启动 1、介绍2、下载apache-skywalking-apm3、解压缩文件4、创建数据库及用户5、修改配置文件6、下载 MySQL JDBC 驱动7、启动 OAP Serve,需要jkd11,需指定jkd版本,可以修改文件oapService.sh8、启动 Web UI,需要jkd11,需指定jkd版本,可以修改文件oapServi…

计算方法实验四 解线性方程组的间接方法

【实验性质】 综合性实验。 【实验目的】 掌握迭代法求解线性方程组。 【实验内容】 应用雅可比迭代法和Gauss-Sediel迭代法求解下方程组: 【理论基础】 线性方程组的数值解法分直接算法和迭代算法。迭代法将方程组的求解转化为构造一个向量序列&…

G919-GAS软件 JSON格式数据通讯协议-阵列数据解析

G919-GAS软件 JSON格式数据通讯协议-阵列数据解析 版本记录 DateAuthorVersionNote2024.04.07Dog TaoV1.0发布通讯协议。2025.05.06Dog TaoV1.11. 增加了【高速采样】模式下的通讯协议。2. 增加了“软件开发建议”小节。 文章目录 G919-GAS软件 JSON格式数据通讯协议-阵列数据…

TCGA数据库临床亚型可用!贝叶斯聚类+特征网络分析,这篇 NC 提供的方法可以快速用起来了!

生信碱移 贝叶斯网络聚类 CANclust是一种基于贝叶斯的聚类方法,系统性地对基因突变、细胞遗传学信息和临床指标进行联合建模,用于多种模态数据的联合聚类分析,并识别在患者群体中反复出现的特征模式。 个体的遗传与环境背景决定其应对疾病的…