(21)python+playwright自动化测试鼠标拖拽总

1.简介

前边拖拽有提到那个反爬虫机制,加了各种参数,以及加载js脚本文件还是有问题,偶尔好像发现了解决问题的办法,看到了黎明的曙光,就说试一下看看行不行,万一实现了。结果试了结果真的OK啊,但是第一次运行可以,后边就不行了,然后将编辑器关闭重启,再次运行又可以,猜测可能是缓冲问题吧,但是具体原因还是没有查到。

所以就加更一篇来记录是如何解决的。而且最近有一些爬虫用户说:在使用 playwright 的时候,提到 playwright 默认是用无痕模式打开的浏览器,很多网站会有反爬机制,使用无痕模式打开的时候功能无法正常使用。问有没有好的办法。答复暂时也没有好办法,也不知道这种解决方法会不会帮到,或者有参考价值。

2.启动浏览器的模式

playwright 提供了 launch_persistent_context 启动浏览器的方法,可以非无痕模式启动浏览器。

无痕模式启动浏览器适合做自动化测试的人员

非无痕模式启动浏览器适合一些爬虫用户人员

2.1无痕模式启动浏览器

launch()方法是无痕模式启动浏览器。

参考代码如下:

# coding=utf-8🔥

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(headless=False)
    context = browser.new_context()
    page = context.new_page()
    page.goto("https://www.baidu.com")

    # do ....
    page.pause()
    browser.close()

无痕模式启动浏览器,会在浏览器右上角出现“无痕模式”:

2.2非无痕模式启动浏览器

如果网站被识别或者被监测无痕模式不能使用,那么可以用 launch_persistent_context()方法非无痕模式启动浏览器。

相关参数说明:

user_data_dir : 用户数据目录,此参数是必须的,可以自定义一个目录
accept_downloads: 接收下载事件
headless: 是否设置无头模式
channel: 指定浏览器类型,默认chromium

参考代码如下:

# coding=utf-8🔥
from playwright.sync_api import sync_playwright

with sync_playwright() as p:

    browser = p.chromium.launch_persistent_context(
        # 指定本机用户缓存地址
        user_data_dir=f"C:\\Users\\DELL\\Desktop\\Chrome\\test",
        # 接收下载事件
        accept_downloads=True,
        # 设置 GUI 模式
        headless=False,
        bypass_csp=True,
        slow_mo=1000,
        channel="chrome"
    )
    page = browser.new_page()
    page.goto("https://www.baidu.com")

    # do ....
    page.pause()
    browser.close()

发现以上代码运行后,会多出一个空白页。如下图所示:

进入launch_persistent_context方法,发现是因为使用launch_persistent_context方法会自动打开一个tab标签页,后面代码browser.new_page()重新打开了一个新的page对象。所以才会多一个空白页。

解决办法很简单,去掉browser.new_page()代码即可。直接用默认打开发tab标签页对象。

参考代码如下:

# coding=utf-8🔥

from playwright.sync_api import sync_playwright

with sync_playwright() as p:

    browser = p.chromium.launch_persistent_context(
        # 指定本机用户缓存地址
        user_data_dir=f"C:\\Users\\DELL\\Desktop\\Chrome\\test",
        # 接收下载事件
        accept_downloads=True,
        # 设置 GUI 模式
        headless=False,
        bypass_csp=True,
        slow_mo=1000,
        channel="chrome"
    )
    page = browser.pages[0]
    page.goto("https://www.baidu.com")

    # do ....
    page.pause()
    browser.close()

运行代码

3.项目实战

这里还用之前的那个实例进行演示,也就是在文章最后提到反爬虫的那篇文章的例子:携程旅行,手机号查单页面的一个滑动,进行项目实战。如下图所示:

3.1代码设计

参考前边提到的方法进行代码设计如下:

3.2参考代码

# coding=utf-8🔥

from playwright.sync_api import Playwright, sync_playwright, expect

def run(playwright: Playwright) -> None:
    browser = playwright.chromium.launch_persistent_context(
        # 指定本机用户缓存地址
        user_data_dir=f"C:\\Users\\DELL\\Desktop\\Chrome\\test",
        # 接收下载事件
        accept_downloads=True,
        # 设置 GUI 模式
        headless=False,
        bypass_csp=True,
        slow_mo=1000,
        channel="chrome"
    )
    page = browser.pages[0]
    page.goto("https://passport.ctrip.com/user/member/fastOrder")
    page.wait_for_timeout(2000)
    #获取拖动按钮位置并拖动  //*[@id="slider"]/div[1]/div[2]
    dropbutton=page.locator("//*[@id='slider']/div[1]/div[2]")
    box=dropbutton.bounding_box()
    page.mouse.move(box['x']+box['width']/2,box['y']+box[ 'height']/2)
    page.mouse.down()
    mov_x=box['x']+box['width']/2+280
    page.mouse.move(mov_x,box['y']+box[ 'height']/2)
    page.mouse.up()
    page.wait_for_timeout(3000)
    browser.close()

with sync_playwright() as playwright:
    run(playwright)

3.3运行代码

1.运行代码,右键Run'Test',控制台输出,如下图所示:

2.运行代码后电脑端的浏览器的动作(可以清楚地的看到滑动后,出现“校验成功,通过”的字样,而不是之前出现的那种反爬虫机制,又弹出选字校验)。如下图所示:

好了,到此大功告成,问题就解决了。

4.小结

1. launch_persistent_context创建的浏览器对象,为什么无法使用browser.new_context()创建上下文?

因为launch_persistent_context字面上意思就已经是一个context上下文对象了,所以无法创建上下文,只能创建page对象。

2.user_data_dir路径参数的作用什么?

user_data_dir是指定浏览器启动的用户数据缓存目录,当指定一个新的目录时,启动浏览器会发现自动生成缓存文件。打开C:\Users\\DELL\Desktop\Chrome\test目录会看到加载的浏览器缓存文件。如下图所示:

3.user_data_dir能不能记住用户登录的状态?

user_data_dir就是你自己定义的打开浏览器保存的用户数据,包含了用户的cookies,所以你只要登录过,就会自动保存。
所以你只要代码打开网站,如果不能通过代码自动登录(可能有一些验证码什么的),你可以断点后手工去登录一次,也会记住cookies。下次代码再打开就不需要登录了。

4.为什么按你的教程,我这个网站就无法保持登录?

能不能保持登录状态,主要看你网站的cookies有效期,有些网站关闭浏览器后就失效了,比如一些银行的网站,你只要关闭浏览器窗口,下次就需要再次登录。
简单来说一句话:你手工去操作一次,关闭浏览器,再打开还要不要登录,如果关闭浏览器需要再次登录,那代码也没法做到保持登录。
有些博客网站,你登录一次,cookies几个月都有效,这种就可以利用缓存的cookies保持登录。

5.为什么网上其他教程user_data_dir写chrome的安装目录?

其实没必要非要写chrome的安装目录"C:\Users\{getpass.getuser()}\AppData\Local\Google\Chrome\UserData"。
如果你写的是系统默认安装目录的用户数据,那你本地浏览器打开后,执行代码就会报错。所以不推荐!

6.默认启动的是chromium浏览器,能不能换成其他的浏览器?

可以通过"channel"参数指定浏览器,可以支持chromium系列:chromium、chrome、chrome-beta、msedge。

7.如何设置窗口最大化?

添加args=['--start-maximized']和no_viewport=True两个参数设置窗口最大化。

browser = p.chromium.launch_persistent_context(
    # 指定本机用户缓存地址
    user_data_dir=f"D:\chrome_userx\yoyo",
    # 接收下载事件
    accept_downloads=True,
    # 设置 GUI 模式
    headless=False,
    bypass_csp=True,
    slow_mo=1000,
    channel="chrome",
    args=['--start-maximized'],
    no_viewport=True
)

或者使用viewport={'width':1920,'height':1080}设置屏幕分辨率

browser = p.chromium.launch_persistent_context(
    # 指定本机用户缓存地址
    user_data_dir=f"D:\chrome_userx\yoyo",
    # 接收下载事件
    accept_downloads=True,
    # 设置 GUI 模式
    headless=False,
    bypass_csp=True,
    slow_mo=1000,
    channel="chrome",
    viewport={'width': 1920, 'height': 1080}
)

 

 

### 使用 PythonPlaywright 绕过验证码的最佳实践 #### 1. 利用机器学习模型识别验证码图像 对于复杂的图形验证码,可以采用预训练的YOLOv5模型来检测和解析验证码中的特定元素。这种方法特别适用于滑动验证场景,在这些情况下,可以通过定位图片缺口的位置来进行自动填充[^2]。 ```python from pathlib import Path import torch def load_model(): model_path = "path/to/yolov5/model" device = 'cuda' if torch.cuda.is_available() else 'cpu' model = torch.hub.load('ultralytics/yolov5', 'custom', path=model_path, force_reload=True).to(device) return model model = load_model() results = model(image) # image 是待处理的验证码截图 ``` #### 2. 自动化交互流程模拟人类行为 为了提高成功率并减少被反作弊机制捕获的风险,应该模仿真实用户的鼠标移动轨迹以及点击间隔时间等细节特征。这通常涉及到生成随机但自然的动作序列,并将其应用于浏览器实例中执行相应的DOM操作[^3]。 ```javascript // JavaScript code snippet to simulate human-like mouse movements using PlayWright API. await page.mouse.move(x_start, y_start); const duration = Math.random() * (maxDuration - minDuration) + minDuration; await page.mouse.down(); for(let i=0;i<steps;i++){ let newX = x_start + ((i/steps)*(x_end-x_start)); await page.mouse.move(newX,y,{ steps: stepCount }); } await page.mouse.up(); ``` #### 3. 处理基于HTML5 canvas绘制的动态验证码 针对某些网站可能使用的canvas技术创建的动态变化型验证码(如拖拽拼图),则需先截取整个页面作为背景图层保存下来;接着利用OpenCV库计算两幅图像之间的差异区域从而找到目标对象的确切坐标位置[^4]。 ```python import cv2 import numpy as np def find_gap_position(bg_img, fg_img): bg_gray = cv2.cvtColor(np.array(bg_img), cv2.COLOR_BGR2GRAY) fg_gray = cv2.cvtColor(np.array(fg_img), cv2.COLOR_BGR2GRAY) diff = cv2.absdiff(bg_gray,fg_gray) _, thresh = cv2.threshold(diff, 50, 255, cv2.THRESH_BINARY) contours,_ = cv2.findContours(thresh.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)[-2:] contour = sorted(contours, key=cv2.contourArea, reverse=True)[0] rect = cv2.minAreaRect(contour) box = cv2.boxPoints(rect) gap_x = int((box[0][0]+box[2][0])/2) return gap_x ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员的世界你不懂

你的鼓励将是我创造的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值