当前位置: 首页 > article >正文

Playwright 解决京东滑块:自动化挑战大揭秘

目录

1. 前言

2. playwright 介绍

2.1 区别和优势

3. playwright 使用

3.1 安装

3.2 第一个playwright脚本

4 定位器

4.1 CSS定位

4.2 XPATH定位

5. Context上下文管理对象

6. 京东滑块验证


1. 前言

如何处理JD的滑块登录?(若只想查看京东滑块,请直接滑到最下面)

平时所使用的自动化登录工具:Selenium,虽然很好,但是在做京东滑块验证的时候,还是会出现被检测的情况,以至于无法通过校验。

于是,我发现了另外一款自动化工具:playwright,也是非常的好用。

接下来,就来见证它的强大吧!

2. playwright 介绍

这就直接copy过来了:

Playwright 是一个用于自动化浏览器操作的开源工具,由 Microsoft 开发和维护。它支持多种浏览器(包括 Chromium、Firefox 和 WebKit)和多种编程语言(如 Python、JavaScript 和 C#),可以用于测试、爬虫、自动化任务等场景。

这是他的官网:

Installation | Playwright Python

当然你会想,这和selenium的区别是什么?有什么优势?

2.1 区别和优势

playwright没有selenium那么臃肿,也没它那么耗费资源,所以它具有以下特性:

  • 多浏览器支持:支持所有主流浏览

  • 更快的执行速度:Playwright 通过使用浏览器的底层调试协议来进行操作

  • 可靠性和稳定性:Playwright 提供了更可靠和稳定的浏览器自动化操作,通过使用浏览器的原生 API 来模拟用户行为,避免了一些传统自动化工具的一些限制和不稳定性

  • 支持跨浏览器和跨平台:Playwright 可以在不同浏览器和不同操作系统上运行

  • selenium是基于http协议,而Playwright是基于websocket协议

  • 支持屏幕录制功能:根据屏幕录制指定生成相关操作代码

可以看到,playwright相比较于selenium和pyppeteer来说,执行速度更快,更加稳定,也更加方便。

3. playwright 使用

3.1 安装

首先需要安装库:

  pip install playwright

除此之外,playwright还提供了安装对应的插件和浏览器功能:

(安装耗时较长)

  playwright install

3.2 第一个playwright脚本

直接附上代码:

from playwright.sync_api import sync_playwright

with sync_playwright() as p:  # 创建playwright管理器(执行结束后,自动关闭)
    bro = p.chromium.launch(headless=False)  # 创建浏览器对象
    page = bro.new_page()  # 新建浏览器页面
    page.goto('https://www.baidu.com')  # 请求该网址
    page.wait_for_timeout(1000)  # 等待1s
    title = page.title()  # 获取标题
    content = page.content()  # 获取内容
    print(title)
    print(content)
    # 关闭
    page.close()
    bro.close()

当然,playwright也是支持异步的:

import asyncio
from playwright.async_api import async_playwright
async def main():
    async with async_playwright() as p:
        bro = await p.chromium.launch(headless=False,slow_mo=2000)
        page = await bro.new_page()
        await page.goto('https://www.baidu.com')
        title = await page.title()
        content = await page.content()
        print(title,content)
        await page.close()
        await bro.close()

asyncio.run(main())

4 定位器

以下开始介绍常用的定位器,用于定位相应的标签,并做出一系列动作,如CSS定位和XPATH定位

4.1 CSS定位

css定位一般是通过ID、标签、Class来进行定位。

语法结构:page.locator()

交互操作:

        1、click() 点击元素

        2、fill() 填充内容

        3、focus() 聚焦于当前标签

        4、inner_text() 获取元素文本

        5、get_attribute('href') 获取元素属性

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    bro = p.chromium.launch(headless=False, slow_mo=2000)
    page = bro.new_page()
    page.goto('https://www.baidu.com')

    # 定位到输入框,进行文本录入
    page.locator('#kw').fill('playwright')  # id定位
    # 定位搜索按钮,进行点击操作
    page.locator('#su').click()
    # 后退操作
    page.go_back()

4.2 XPATH定位

其实就跟上面一样:

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    bro = p.chromium.launch(headless=False,slow_mo=2000)
    page = bro.new_page()
    page.goto('https://www.bilibili.com/')

    #xpath定位
    page.locator('//*[@id="nav-searchform"]/div[1]/input').fill('Python')
    page.locator('//*[@id="nav-searchform"]/div[2]').click()

    page.close()
    bro.close()

5. Context上下文管理对象

浏览器的上下文管理对象Context可以用于管理Context打开/创建的多个page页面。并且可以创建多个Context对象,那么不同的Context对象打开/创建的page之间是相互隔离的(每个Context上下文都有自己的Cookie、浏览器存储和浏览历史记录)。

 

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    bro = p.chromium.launch(headless=False, slow_mo=2000)

    # 创建管理对象
    context = bro.new_context()

    page = context.new_page()
    page.goto('https://www.baidu.com')

    a_list = page.locator('//*[@id="s-top-left"]/a').all()

    for i in a_list:
        i.click()

    # 所有page页面
    pages = context.pages

    for page in pages:
        print(page.title())

    page.close()
    bro.close()

6. 京东滑块验证

好了,相信你已经对playwright有了基本了解,更多方法可自行查看官方文档。

所有的自动化工具都是一样的,最主要的还是定位元素执行一些操作。

以下就是京东滑块代码,其中采用了图鉴进行滑块验证码识别:

Tu.py

import base64
import json
import requests
# 一、图片文字类型(默认 3 数英混合):
# 1 : 纯数字
# 1001:纯数字2
# 2 : 纯英文
# 1002:纯英文2
# 3 : 数英混合
# 1003:数英混合2
#  4 : 闪动GIF
# 7 : 无感学习(独家)
# 11 : 计算题
# 1005:  快速计算题
# 16 : 汉字
# 32 : 通用文字识别(证件、单据)
# 66:  问答题
# 49 :recaptcha图片识别
# 二、图片旋转角度类型:
# 29 :  旋转类型
#
# 三、图片坐标点选类型:
# 19 :  1个坐标
# 20 :  3个坐标
# 21 :  3 ~ 5个坐标
# 22 :  5 ~ 8个坐标
# 27 :  1 ~ 4个坐标
# 48 : 轨迹类型
#
# 四、缺口识别
# 18 : 缺口识别(需要2张图 一张目标图一张缺口图)
# 33 : 单缺口识别(返回X轴坐标 只需要1张图)
# 34 : 缺口识别2(返回X轴坐标 只需要1张图)
# 五、拼图识别
# 53:拼图识别
def base64_api(uname, pwd, img, typeid):
    with open(img, 'rb') as f:
        base64_data = base64.b64encode(f.read())
        b64 = base64_data.decode()
    data = {"username": uname, "password": pwd, "typeid": typeid, "image": b64}
    result = json.loads(requests.post("http://api.ttshitu.com/predict", json=data).text)
    if result['success']:
        return result["data"]["result"]
    else:
        #!!!!!!!注意:返回 人工不足等 错误情况 请加逻辑处理防止脚本卡死 继续重新 识别
        return result["message"]
    return ""


def getImgCodeText(imgPath,imgType):#直接返回验证码内容
    #imgPath:验证码图片地址
    #imgType:验证码图片类型
    result = base64_api(uname='账号', pwd='密码', img=imgPath, typeid=imgType)
    return result

main.py

"""
京东滑块:https://passport.jd.com/new/login.aspx?
"""
from playwright.sync_api import sync_playwright
from Tu import getImgCodeText
from urllib import request


# 有的检测移动速度的 如果匀速移动会被识别出来,来个简单点的渐进
def get_track(distance):  # distance为传入的总距离
    # 移动轨迹
    track = []
    # 当前位移
    current = 0
    # 减速阈值
    mid = distance * 4 / 5
    # 计算间隔
    t = 0.2
    # 初速度
    v = 1
    while current < distance:
        if current < mid:
            # 加速度为2
            a = 4
        else:
            # 加速度为-2
            a = -3
        v0 = v
        # 当前速度
        v = v0 + a * t
        # 移动距离
        move = v0 * t + 1 / 2 * a * t * t
        # 当前位移
        current += move
        # 加入轨迹
        track.append(round(move))
    return track


with sync_playwright() as p:
    bro = p.chromium.launch(headless=False)
    page = bro.new_page()
    page.goto('https://passport.jd.com/new/login.aspx?')

    page.locator('//*[@id="loginname"]').fill('123456@qq.com')
    page.wait_for_timeout(1000)
    page.locator('//*[@id="nloginpwd"]').fill('1234567')
    page.wait_for_timeout(1000)
    page.locator('//*[@id="loginsubmit"]').click()

    page.wait_for_timeout(2000)

    bg_img_src = page.locator('//*[@id="JDJRV-wrap-loginsubmit"]/div/div/div/div[1]/div[2]/div[1]/img').get_attribute(
        'src')

    # 两张图片保存起来
    request.urlretrieve(bg_img_src, "background.png")

    # 基于图鉴平台实现计算滑动距离
    distance = getImgCodeText('background.png', 33)
    distance = int(distance)
    print('距离:', distance)

    # 定位到滑块标签
    slide = page.locator('//*[@id="JDJRV-wrap-loginsubmit"]/div/div/div/div[2]/div[3]')

    # 找到滑块在当前页面的坐标(这个会返回一个字典里边四个数字)
    # {'x': 123, 'y': 1213, 'width': 12, 'height': 12}
    box = slide.bounding_box()

    # 让鼠标移动到滑块标签的中间上
    page.mouse.move(box["x"] + box["width"] / 2, box["y"] + box["height"] / 2)
    # 按下鼠标
    page.mouse.down()
    # 滑块最左边的位置,由于会有误差,因此需要调整后面的数值
    x = box["x"] + 24
    # 滑动的长度放到轨迹加工一下得到一个轨迹
    tracks = get_track(distance)
    for track in tracks:
        # 循环鼠标按照轨迹移动
        page.mouse.move(x + track, 0)
        x += track
    # 移动结束鼠标释放
    page.mouse.up()

    page.wait_for_timeout(5000)
    page.close()
    bro.close()

最重要的是,由于有误差,并不能百分百成功,需要微调这里的数值:


http://www.kler.cn/a/450018.html

相关文章:

  • SpringCloud 入门(4)—— 网关
  • 【Linux探索学习】第二十三弹——理解文件系统:认识硬件、探索文件在硬件上的存储问题
  • Linux文件目录 --- 移动和改名命令MV、强制移动、试探性移动过、按时间移动
  • 工厂防静电监控系统设备静电监控仪的关键作用
  • springboot中使用gdal将表中的空间数据转shapefile文件
  • jsp | servlet | spring forEach读取不了对象List
  • MLU运行Stable Diffusion WebUI Forge【flux】
  • springBoot Bean加载流程
  • k8s总结
  • 汉塔科技-上网行为管理系统 ping.php 远程命令执行漏洞复现
  • 梳理你的思路(从OOP到架构设计)_设计模式Observer模式
  • OPPO Android面试题及参考答案 (上)
  • 006_ipc概述及共享内存
  • Linux 下SVN新手操作手册
  • 解析mysqlbinlog
  • Word使用分隔符实现页面部分分栏
  • Kotlin - 协程结构化并发Structured Concurrency
  • CSS|13 position属性
  • [c++11(二)]Lambda表达式和Function包装器及bind函数
  • 数据结构---------二叉树前序遍历中序遍历后序遍历
  • MyBatis执行完sql后,返回的数值代表的意思
  • 基于PX4的多无人机集群中的的配置
  • 【软考高级】系统架构设计师复习笔记-精华版
  • 【C语言】判断回文
  • #error: WinSock.h has already been included解决方案
  • 解决PotPlayer无法播放S/W HEVC(H265)解码的视频