playwright实战篇(tx、ali225)

news2024/12/31 6:09:18
人人都笑金角,人人都是金角
推荐文章:
1、https://playwright.dev/python/docs/api/class-playwright  //官方文档
2、https://cuiqingcai.com/36045.html  //崔庆才教程
3、https://github.com/qqq732004709/  //实战参考
4、https://www.cnblogs.com/carl-/p/15761861.html //实战参考
5、https://www.cnblogs.com/james-wangx/p/16106304.html //实战参考

案例一:tx滑块(playwright)

目标网站:aHR0cHM6Ly93d3cudXJidGl4LmhrL2xvZ2lu

1、创建Chromium实例(如果不设置为 False,默认是无头模式启动浏览器)

async with async_playwright() as p:
    browser = await p.chromium.launch(headless=False, args=['--start-maximized'])

2、最大化窗口

context = await browser.new_context(viewport={"width": 1920, "height": 1080}, no_viewport=True)

3、新建标签页

page = await context.new_page()

4、加载过检测js

await page.add_init_script(js) #stealth.min.js

5、监听response事件

async def on_response(response):
    if '/cap_union_new_getcapbysig' in response.url and response.status == 200:
        #对背景图以及滑块图进行拦截然后保存
        if 'img_index=1' in response.url:
            with open("bg_picture.jpg", "wb") as f:
                f.write(requests.get(response.url).content)
        elif 'img_index=0' in response.url:
            with open("cut_picture.png", "wb") as f:
                f.write(requests.get(response.url).content)
        print("response.url:", response.url)
    if 'cap_union_new_verify' in response.url and response.status == 200:
        #滑块通过后获取参数
        result = await response.text()
        print("response.url:", response.url,result)
        
page.on('response',on_response)

6、打开网页、触发滑块

await page.goto('aHR0cHM6Ly93d3cudXJidGl4LmhrL2xvZ2lu')
await page.wait_for_timeout(1500)
await page.click('xpath=//*[@id="root"]/div/div[3]/div/div/div[5]/div/div') 
await page.wait_for_timeout(500)
await page.click('xpath=//*[@id="root"]/div/div[3]/div/div/div[8]/div[2]/div')

7、识别坐标

def get_gap_offset():
    """
    识别坐标,滑块的图片需要切割
    """
    det = ddddocr.DdddOcr(det=False, ocr=False, show_ad=False)
    img = Image.open('cut_picture.png')
    region = img.crop((160, 508, 243, 595))  #
    region.save(f'cut_picture.png')
    with open('bg_picture.jpg', 'rb') as f:
        target_bytes = f.read()
    with open('cut_picture.png', 'rb') as f:
        background_bytes = f.read()
    res = det.slide_match(target_bytes, background_bytes, simple_target=True)
    print("识别到的坐标位置:", res)
    distance = int(res['target'][0])
    return distance

8、找到滑动起始点,并滑动

async def move_down(page):
    #定位iframe
    new_frame = page.frame_locator('iframe[id="tcaptcha_iframe_dy"]')
    #定位起始点
    move_tag = new_frame.locator('xpath=//*[@id="tcOperation"]/div[6]')
    #找到这个元素在当前页面的坐标
    box = await move_tag.bounding_box() 
    print("目前点击的位置",box)
    # 讲鼠标移动到到其实元素的中心
    await page.mouse.move(box["x"] + box["width"] / 2, box["y"] + box["height"] / 2)  
    # 按下鼠标
    await page.mouse.down() 
    #延时1.2s
    await page.wait_for_timeout(1200)
    # 这里获取到x坐标中心点位置
    x = box["x"] + box["width"] / 2 
    #识别到坐标后与网页上的比例
    distance = int(get_gap_offset()/1.97)-30
    #轨迹
    move_distance = get_track_list(distance)
    print("最终坐标:",distance,"轨迹:",move_distance)
    for i in move_distance:
        x += i
        await page.mouse.move(x, box["y"])
    await page.mouse.up()

9、关闭窗口

await browser.close()

至此tx滑块的分析就结束了
在这里插入图片描述

然后我还写了一版selenium的,相比于playwright就会麻烦一些
案例一:tx滑块(selenium)

对于我们日常使用而言两者主要区别在于:
1、selenium只支持同步,playwright可以支持异步的
2、操作iframe,selenium来回切换iframe非常麻烦,而playwright只需要定位元素即可
2、在监听请求这一点上,playwright的page.on非常好用,而selenium一般是借助browsermobproxy通过代理的方式进行拦截
   使用方式:(1)https://github.com/lightbody/browsermob-proxy/releases,下载并解压
            (2)安装证书,参考链接https://www.bilibili.com/read/cv21263644/
            (3)调用方式
		        server = Server('browsermob-proxy-2.1.4/bin/browsermob-proxy')
		        server.start()
		        proxy = server.create_proxy(params={'trustAllServers':'true'})
		        option = ChromeOptions()
		        option.add_argument('--proxy-server={0}'.format(self.proxy.proxy))
		        driver = webdriver.Chrome(options=option)

这里就不细致讲解了,主要代码如下

class Tencent():
    def __init__(self):
        server = Server('browsermob-proxy-2.1.4/bin/browsermob-proxy')
        server.start()
        self.proxy = server.create_proxy(params={'trustAllServers':'true'})
        self.url = 'aHR0cHM6Ly93d3cudXJidGl4LmhrL2xvZ2lu'
        option = ChromeOptions()
        option.add_experimental_option('excludeSwitches', ['enable-automation'])
        option.add_experimental_option('useAutomationExtension', False)
        option.add_argument('--proxy-server={0}'.format(self.proxy.proxy))
        self.proxy.new_har(options={'captureContent': True,'captureHeaders': True})
        self.driver = webdriver.Chrome(options=option)
        self.driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {
            'source': 'Object.defineProperty(navigator,"webdriver",{get: () => undefined})'
        })
        with open('stealth.min.js') as f:
            js = f.read()
        self.driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {"source": js})
        self.driver.maximize_window()
        self.det = ddddocr.DdddOcr(det=False, ocr=False, show_ad=False)
        self.headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36'}

    def index(self):
        """
        主流程
        """
        self.driver.get(self.url)
        time.sleep(5)
        print("正在打开网页~~~")
        self.driver.find_element(by=By.XPATH, value=f'//*[@id="root"]/div/div[3]/div/div/div[5]/div/div').click()
        time.sleep(1)
        self.driver.find_element(by=By.XPATH, value=f'//*[@id="root"]/div/div[3]/div/div/div[8]/div[2]/div').click()
        time.sleep(5)
        self.driver.switch_to.frame('tcaptcha_iframe_dy')
        bg_style = self.driver.find_element('id','slideBg').get_attribute("style")
        cut_style = self.driver.find_element(by=By.XPATH, value=f'//*[@id="tcOperation"]/div[8]').get_attribute("style")
        bg_url = re.findall('url\("(.*?)"\)',str(bg_style))[0]
        cut_url = re.findall('url\("(.*?)"\)', str(cut_style))[0]
        print("获取到背景图片url:",bg_url)
        print("获取到滑块图片url:",cut_url)
        with open("bg_picture.jpg", "wb") as f:
            f.write(requests.get(bg_url).content)
        with open("cut_picture.png", "wb") as f:
            f.write(requests.get(cut_url).content)

    def get_gap_offset(self):
        """
        识别坐标
        """
        img = Image.open('cut_picture.png')
        region = img.crop((160, 508, 243, 595))  #
        region.save(f'cut_picture.png')

        with open('bg_picture.jpg', 'rb') as f:
            target_bytes = f.read()
        with open('cut_picture.png', 'rb') as f:
            background_bytes = f.read()
        res = self.det.slide_match(target_bytes, background_bytes, simple_target=True)
        print("识别到的坐标位置:",res)
        distance = int(res['target'][0])
        return distance

    def get_track(self, offset):
        '''
        计算滑块的移动轨迹
        '''
        offset -= 30  # 滑块并不是从0开始移动,有一个初始值
        a = offset / 4
        track = [a, a, a, a]
        return track

    def shake_mouse(self):
        """
        模拟人手释放鼠标抖动
        """
        ActionChains(self.driver).move_by_offset(xoffset=-2, yoffset=0).perform()
        ActionChains(self.driver).move_by_offset(xoffset=2, yoffset=0).perform()

    def operate_slider(self, track):
        """
        拖动滑块
        :param track: 运动轨迹
        """
        #  定位到拖动按钮
        slider_bt = self.driver.find_element(by=By.XPATH,value ='//*[@id="tcOperation"]/div[6]')
        # 点击拖动按钮不放
        ActionChains(self.driver).click_and_hold(slider_bt).perform()
        # 按正向轨迹移动
        for i in track:
            ActionChains(self.driver).move_by_offset(xoffset=i, yoffset=0).perform()
            time.sleep(random.random() / 100)  # 每移动一次随机停顿0-1/100秒之间骗过了极验,通过率很高
        time.sleep(random.random())
        # 按逆向轨迹移动
        back_tracks = [-1, -0.5, -1]
        for i in back_tracks:
            time.sleep(random.random() / 100)
            ActionChains(self.driver).move_by_offset(xoffset=i, yoffset=0).perform()
        # 模拟人手抖动
        self.shake_mouse()
        time.sleep(random.random())
        # 松开滑块按钮
        ActionChains(self.driver).release().perform()
        time.sleep(2)

    def login(self):
        '''
        实现主要的登陆逻辑
        '''
        self.index()
        distance = self.get_gap_offset()
        distance = int(distance/1.97)
        track = self.get_track(distance)
        self.operate_slider(track)

        result = self.proxy.har
        for entry in result['log']['entries']:
            if entry['request']['url'] == 'https://t.captcha.qq.com/cap_union_new_verify':
                print(entry['request']['url'],entry['response']['content'])
                print(entry['response']['content']['text'])

案例二:阿里225(playwright)

目标网站:aHR0cHM6Ly9wYXNzcG9ydC5kYW1haS5jbi9sb2dpbg==

1、前面的初始化流程

async with async_playwright() as p:
        browser = await p.chromium.launch(headless=False, args=['--start-maximized'])
	    context = await browser.new_context(viewport={"width": 1920, "height": 1080}, no_viewport=True)
	    context.set_default_timeout(8000)
	    page = await context.new_page()
	    await page.add_init_script(js)
	    print("打开网页~~~")
	    await page.goto('aHR0cHM6Ly9wYXNzcG9ydC5kYW1haS5jbi9sb2dpbg==')
	    await page.wait_for_timeout(1000)
	    page.on('response', on_response)

2、输入账号密码

 #这里需要注意这个iframe,前面的iframe和后面出滑块之后的iframe属于包含关系
 new_frame = page.frame_locator('iframe[id="alibaba-login-box"]')
 await page.wait_for_timeout(1000)
 await new_frame.locator('#fm-login-id').fill("正确的手机号码")
 await page.wait_for_timeout(1000)
 await new_frame.locator('#fm-login-password').fill("错误的密码") 
 await page.wait_for_timeout(1000)
 await new_frame.get_by_role("button", name="登录").click()
 await page.wait_for_timeout(1000)

3、强制弹出滑块,并判断

 #这里为了让它出滑块要先输出错误的密码,然后一直click,直到出滑块为止
while True:
   try:
       new_frame2 = new_frame.frame_locator('iframe[id="baxia-dialog-content"]')
       move_tag = new_frame2.locator('xpath=//*[@id="nc_1_n1z"]')
       number = await move_tag.count()
       if number>=1:
           box = await move_tag.bounding_box()
           print("目前点击的位置", box)
           break
       else:
           print(f"没出滑块,重新点击")
           await page.wait_for_timeout(1000)
           await new_frame.get_by_role("button", name="登录").click()
   except:
       await new_frame.get_by_role("button", name="登录").click()

4、定位以及滑动

async def move_down(page,box):
    await page.mouse.move(box["x"] + box["width"] / 2, box["y"] + box["height"] / 2)
    await page.mouse.down()  # 按下鼠标
    await page.wait_for_timeout(1200)
    x = box["x"] + box["width"] / 2  # 这里获取到x坐标中心点位置
    move_distance = get_track_list(265)
    print("轨迹:",move_distance)
    for i in move_distance:
        x += i
        await page.mouse.move(x, box["y"])
    await page.mouse.up()
    await page.wait_for_timeout(500)

至此ali滑块的分析就结束了
在这里插入图片描述

当脚下的路走起来比以前轻松了,是不是该问自己是否在走下坡路了,我也不知道呢

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

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

相关文章

asp.net mvc网上书店购物系统(带项目文档)

c#_asp.net mvc网上书店购物系统(带项目文档) mvc网上书店购物系统 主要技术: 基于asp.net mvc架构和sql server数据库,并采用EF实体模型开发。 功能模块: 系统包括前台和后台两个部分,用户可在前台浏览…

KL散度和交叉熵的对比介绍

KL散度(Kullback-Leibler Divergence)和交叉熵(Cross Entropy)是在机器学习中广泛使用的概念。这两者都用于比较两个概率分布之间的相似性,但在一些方面,它们也有所不同。本文将对KL散度和交叉熵的详细解释…

学系统集成项目管理工程师(中项)系列03_职业道德规范

1. 职业道德 1.1. 涵盖了从业人员与服务对象、职业与职工、职业与职业之间的关系 1.2. 是所有从业人员在职业活动中应该遵循的行为准则 1.3. 包括爱岗敬业、诚实守信、办事公道、服务群众和奉献社会 2. 道德 2.1. 通常与法律相对应,具有非强制性 2.2. 指人们依…

《花雕学AI》26:多维度了解ChatGPT思维链提示的原理、方法、使用和发展的22个问题

早上5点起床,没有去打羽毛球,打开电脑,漫无边际的浏览,偶然发现了一个提法:ChatGPT思维链提示。于是,我使用与ChatGPT同源技术的新Bing引擎(GPT-4),来进行搜索与了解相关…

基于在线优化的快速模型预测控制仿真Fast_MPC(Matlab代码实现)

目录 💥1 概述 📚2 运行结果 🎉3 参考文献 👨‍💻4 Matlab代码 💥1 概述 ​模型预测控制(Model Predictive Control,MPC)是一种基于在线计算的控制优化算法,能够统一处理带约束的多参数优化控制问题。…

ESP8266 最简单的OTA升级模式

最近在做一个项目时有OTA的需求,之前是通过arduino自带的ota模式,虽说也可以用,但操作比较麻烦,昨晚在网上搜索相关教程,发现了使用巴法云来实现ota的功能,现分享如下 1、首先要让你的设备联网 2、注册巴法…

jsp基础语法

前提 安装jdk参考 下载tomcat解压&#xff0c;运行tomcat不报错即可 第一个jsp程序 切换到webapps下ROOT文件夹下&#xff0c;将除了WEB-INF文件外的全部内容删除&#xff0c;新建index.jsp index.jsp内容如下 <!DOCTYPE html> <html lang"zh-CN"&g…

React Proxy 详细流程与配置方式(webpack、setupProxy.js、package.json)

一、 package.json 配置方式 全部以 GET 请求为例&#xff0c;每次修改配置后&#xff0c;重启项目&#xff0c;否则不生效。 访问 http://127.0.0.1:6000/api/user/list 接口为例检查自己脚手架版本 $ create-react-app -V若脚手架版本在 2.0 以下&#xff0c;可以使用对象类型…

【C++】deque的实现原理简单介绍

前言 deque被称为双端队列&#xff0c;它的出现主要是为了结合vector和list的优点并减小它们的缺点&#xff0c;实际上deque确实结合了vector和list的优点减小了它们的缺点&#xff0c;但是它的结合也让它自己的优点没有原始的vector和list那么极致&#xff0c;导致deque变得很…

C++好难(1):C++的入门

目录 前言&#xff1a; C的历史&#xff1a; c的领域 1.C的关键字&#xff1a; 2.命名空间 2.1命名空间的定义&#xff1a; 1&#xff09;命名空间的普通定义&#xff1a; 2&#xff09;命名空间的嵌套定义&#xff1a; 3&#xff09;命名空间相同的处理&#xff1a; …

没有公网IP,自建网站如何让外网访问?

受创业潮影响&#xff0c;身边很多朋友都自己开公司创业了&#xff0c;作为一个IT行业从业者&#xff0c;我就莫名的开始忙起来了&#xff0c;因为掌握编程技术&#xff0c;朋友们经常找到我&#xff0c;让我帮他们做公司网站。但是存在一个无法回避的问题&#xff0c;就是我的…

0/1背包问题——从LeetCode题海中总结常见套路

目录 问题讨论 01背包问题公式 为什么状态压缩到一维时候需要逆序&#xff1f; 怎样求次数&#xff1f; 转化成最大和sum/2的01背包&#xff1a;LeetCode.416.分割等和子集 转化成最大和sum/2的01背包&#xff1a;LeetCode1049.最后一块石头的重量II LeetCode.494.目标和…

微软文字转语音不能试用了,分享三个方法给大家!

最近很多小伙伴告诉我&#xff0c;微软文字转语音不能在线试用了&#xff0c;这是因为微软关闭了官方的使用页面&#xff0c;所以现在不能直接使用微软的网页版进行文字转语音了。 那么我们还有没有更好的方法去“白嫖”微软的文字转语音呢&#xff1f; 答案是肯定的&#xf…

初识NoSQL(一文读懂)

最近参加了Oracle的数据库培训&#xff0c;对NoSQL非常好奇&#xff0c;总结一下关于NoSQL的认识。 NoSQL是Not Only SQL&#xff0c;并不是去除掉SQL&#xff0c;泛指非关系型的数据库。关系&#xff0c;指关系模型&#xff0c;具体指同一个对象在不同属性上的值 以及 不同对…

一个AK/SK泄露检测的实现思路

01、简介 在企业上云的过程中&#xff0c;AK/SK泄露导致的数据泄露事件屡见不鲜。在企业混合云架构下&#xff0c;公有云和私有云都存在大量的AccessKey&#xff0c;如何有效地检测可能的AK/SK泄露事件&#xff0c;一直困扰着企业的安全人员。 本文提供了一种比较容易实现的思路…

UART协议学习——异步全双工串行通信方式

文章目录 前言一、简介1、优点2、缺点 二、数据格式三、波特率1、定义2、波特率和采样频率 四、常见接口电平1、TTL电平2、RS232&#xff08;负逻辑&#xff09;3、RS485 前言 2023.4.22 世界地球日 一、简介 UART&#xff1a;Universal Asynchronous Receiver/Transmitter&a…

Albert-Z-Guo/Deep-Reinforcement-Stock-Trading

深加固股票交易 该项目打算在投资组合管理中利用深度强化学习。框架结构的灵感来自Q-Trader。代理人的奖励是在每个行动步骤评估的未实现净利润&#xff08;意味着股票仍在投资组合中且尚未兑现&#xff09;。对于每一步的不作为&#xff0c;投资组合中都会增加负惩罚&#xf…

USMART 函数错误解决方法

身为电子工程师&#xff0c;看了马斯克的星舰飞船&#xff0c;真是太帅了&#xff1b; 深知一个良好的测试环境对产品性能的影响&#xff0c;对工作效率的提升。 小资源MCU调试代码的工具USMART 使用起来。 移植的文章网上有很多&#xff0c;但是对移植过程中使用错误的文章…

mybatisPlus拦截器使用demo

概述 顾名思义&#xff0c;就是一个拦截器&#xff0c;和springmvc的拦截器&#xff0c;servlet的过滤器差不多&#xff0c;就是在执行前拦了一道&#xff0c;里面可以做一些自己的事情。 平时用的mybatisPlus较多&#xff0c;直接以com.baomidou.mybatisplus.extension.plug…

VUE中使用element-china-area-data

使用element-china-area-data的中国省市区级联数据编写城市选择器。以下为解决效果图&#xff1a; &#xff08;1&#xff09;安装 npm install element-china-area-data -S &#xff08;2&#xff09;引入 import { regionData, CodeToText, TextToCode } from ‘element-ch…