《刚刚问世》系列初窥篇-Java+Playwright自动化测试-23- 操作鼠标拖拽 - 番外篇(详细教程)

发布于:2025-02-16 ⋅ 阅读:(40) ⋅ 点赞:(0)

拉票

亲爱的小伙伴们或者童鞋们,喜欢宏哥文章的,请动动你们发财小手,给我投投票票 。
祝2025小伙伴们工作顺利,家庭和睦,心想事成,财源滚滚!
我的票还有7票,互票的朋友私信给我。

投票链接:https://www.csdn.net/blogstar2024/detail/296

1.简介

跟随宏哥学习的小伙伴或者童鞋们想必已经在宏哥Python+Playwright系列文章中知道宏哥如何处理前边文章中提到的反爬虫机制。今天跟随宏哥看一下java语言是如何处理的,已经按照之前的处理方式是否可以成功的处理呢?那么接下来就随宏哥一步步来探索这个未知之谜。好了废话不说,直接进入今天的主题。

2.启动浏览器的模式

宏哥按照自己的理解将其分为两种启动模式,一种是:无痕模式启动浏览器,另一种是:非无痕模式启动浏览器。

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

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

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

2.1launchPersistentContext

官方API的文档地址:浏览器类型 |Playwright Java

返回持久性浏览器上下文实例。

启动使用位于 userDataDir 的持久性存储的浏览器,并返回唯一的上下文。关闭此上下文将自动关闭浏览器。

2.2无痕模式启动浏览器

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

参考代码如下:

package com.bjhg.playwright;

import com.microsoft.playwright.Browser;
import com.microsoft.playwright.BrowserContext;
import com.microsoft.playwright.BrowserType;
import com.microsoft.playwright.Page;
import com.microsoft.playwright.Playwright;

/**
 * @author 北京-宏哥
 * 
 * @公众号:北京宏哥(微信搜索,关注宏哥,提前解锁更多测试干货)
 * 
 * 《刚刚问世》系列初窥篇-Java+Playwright自动化测试-23- 操作鼠标拖拽 - 番外篇(详细教程)
 *
 * 2024年02月14日
 */
public class Test_Drag {
    
    public static void main(String[] args) {
        try (Playwright playwright = Playwright.create()) {
          //使用chromium浏览器,# 浏览器配置,设置以GUI模式启动Chrome浏览器(要查看浏览器UI,在启动浏览器时传递 headless=false 标志。您还可以使用 slowMo 来减慢执行速度。
          Browser browser = playwright.chromium().launch(new BrowserType.LaunchOptions().setHeadless(false).setSlowMo(3000));
          BrowserContext context = browser.newContext();
          //创建page
          Page page = context.newPage();
          //浏览器打开百度
          page.navigate("https://www.cnblogs.com/du-hong");
          //关闭page
          page.close();
          //关闭browser
          browser.close();
        }
      }
}

2.无痕模式启动浏览器,会在浏览器右上角出现“无痕模式”,如下图所示:

2.3非无痕模式启动浏览器

1.如果网站被反爬虫机制识别或者被监测无痕模式不能使用,那么可以用launchPersistentContext()方法进行非无痕(有痕迹)模式启动浏览器。

相关参数说明:

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

参考代码如下:

package com.bjhg.playwright;

import java.io.File;
import com.microsoft.playwright.BrowserContext;
import com.microsoft.playwright.BrowserType;
import com.microsoft.playwright.Page;
import com.microsoft.playwright.Playwright;

/**
 * @author 北京-宏哥
 * 
 * @公众号:北京宏哥(微信搜索,关注宏哥,提前解锁更多测试干货)
 * 
 * 《刚刚问世》系列初窥篇-Java+Playwright自动化测试-23- 操作鼠标拖拽 - 番外篇(详细教程)
 *
 * 2025年02月14日
 */
public class Test_Dialog {
    
    public static void main(String[] args) {
        try (Playwright playwright = Playwright.create()) {
            
            BrowserType.LaunchPersistentContextOptions launch=new BrowserType.LaunchPersistentContextOptions(); 
            launch.setViewportSize(1920,1080);
            launch.setAcceptDownloads(true);
            launch.setChannel("chrome");
            launch.setHeadless(false);
            launch.setSlowMo(3000); 
            BrowserContext browserContext = playwright.chromium().launchPersistentContext(new File("C:\\Users\\Administrator\\Desktop\\test").toPath(),launch); 
            Page page = browserContext.newPage(); 
            
            page.navigate("https://www.baidu.com");
             
            System.out.println("Test Pass");
             
            //关闭page
            page.close();
            //关闭browser
            browserContext.close();
        }
    }
}

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

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

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

参考代码如下:

package com.bjhg.playwright;

import java.io.File;
import com.microsoft.playwright.BrowserContext;
import com.microsoft.playwright.BrowserType;
import com.microsoft.playwright.Page;
import com.microsoft.playwright.Playwright;

/**
 * @author 北京-宏哥
 * 
 * @公众号:北京宏哥(微信搜索,关注宏哥,提前解锁更多测试干货)
 * 
 * 《刚刚问世》系列初窥篇-Java+Playwright自动化测试-23- 操作鼠标拖拽 - 番外篇(详细教程)
 *
 * 2025年02月14日
 */
public class Test_Dialog {
    
    public static void main(String[] args) {
        try (Playwright playwright = Playwright.create()) {
            
            BrowserType.LaunchPersistentContextOptions launch=new BrowserType.LaunchPersistentContextOptions(); 
            launch.setViewportSize(1920,1080);
            launch.setAcceptDownloads(true);
            launch.setChannel("chrome");
            launch.setHeadless(false);
            launch.setSlowMo(3000); 
            BrowserContext browserContext = playwright.chromium().launchPersistentContext(new File("C:\\Users\\Administrator\\Desktop\\test").toPath(),launch); 
            
//            Page page = browserContext.newPage(); 
            Page page = browserContext.pages().get(0);
            page.navigate("https://www.baidu.com");
             
            System.out.println("Test Pass");
             
            //关闭page
            page.close();
            //关闭browser
            browserContext.close();
        }
    }
}

运行代码如下(可以清楚地看到没有 新增的空白页面了):

3.项目实战

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

3.1代码设计

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

3.2参考代码
package com.bjhg.playwright;

import java.io.File;

import com.microsoft.playwright.BrowserContext;
import com.microsoft.playwright.BrowserType;
import com.microsoft.playwright.Locator;
import com.microsoft.playwright.Page;
import com.microsoft.playwright.Playwright;

/**
 * @author 北京-宏哥
 * 
 * @公众号:北京宏哥(微信搜索,关注宏哥,提前解锁更多测试干货)
 * 
 * 《刚刚问世》系列初窥篇-Java+Playwright自动化测试-23- 操作鼠标拖拽 - 番外篇(详细教程)
 *
 * 2025年02月14日
 */
public class Test_Dialog {
    
    public static void main(String[] args) {
        try (Playwright playwright = Playwright.create()) {
            
            BrowserType.LaunchPersistentContextOptions launch=new BrowserType.LaunchPersistentContextOptions(); 
            launch.setViewportSize(1920,1080);
            launch.setAcceptDownloads(true);
            launch.setChannel("chrome");
            launch.setHeadless(false);
            launch.setSlowMo(5000); 
            launch.setBypassCSP(true);
            
            BrowserContext browserContext = playwright.chromium().launchPersistentContext(new File("C:\\Users\\Administrator\\Desktop\\test").toPath(),launch); 
            
//            Page page = browserContext.newPage(); 
            Page page = browserContext.pages().get(0);
            //3.浏览器访问demo
            page.navigate("https://passport.ctrip.com/user/reg/home");
            
            page.locator("//*[@id='agr_pop']/div[3]/a[2]").click();
            //4.开始拖拽
            //获取拖动按钮位置并拖动
            Locator slider = page.locator("//*[@id='slideCode']/div[1]/div[2]");
            // 使用鼠标滑动滑块
            page.mouse().move(slider.boundingBox().x + slider.boundingBox().width / 2, slider.boundingBox().y + slider.boundingBox().height / 2);
            page.mouse().down();
            // 根据滑动的范围,这里使用滑动最大距离
            page.mouse().move(slider.boundingBox().x + slider.boundingBox().width / 0.5+380, slider.boundingBox().y + slider.boundingBox().height / 2);
            page.mouse().up();
            //断点调试
            page.pause();
            System.out.println("Test Pass");
            
            //关闭page
            page.close();
            //关闭browser
            browserContext.close();
        }
    }
}
3.3运行代码

1.运行代码,右键Run As->Java Application,就可以看到控制台输出,如下图所示:

2.运行代码后电脑端的浏览器的动作((可以清楚地的看到滑动后,又出现了反爬虫机制,又弹出选字校验))。如下图所示:

4.小结

宏哥在实践的过程中,发现无论手动还是利用上边的代码进行自动化测试都会出现那个反爬虫的机制弹出,因此宏哥怀疑最可能的问题就是由于宏哥近期频繁访问演示,可能被反爬虫的机制判断后,进行了IP锁定,因此会出现这种情况,因为宏哥在第一次进行手动滑动验证的时候,就没有出现。所以宏哥怀疑是被锁定了。一开始宏哥以为是缓冲的问题,宏哥清除浏览器缓冲和历史记录,然后重启电脑最后结果仍然是一样。所以宏哥怀疑被网站的反爬虫锁定IP,最后经过Python和Java的这部分实践,宏哥觉得这种有痕迹的启动模式其实是说白了,就是启动本地安装的浏览器进行自动化测试,而非我们一开始搭建环境时下载的浏览器。因为宏哥在执行代码的过程中报了一个无法找到本地安装chrome的可执行文件的路劲的错误,将其安装文件拷贝到此路径下,代码运行正常没有报错。宏哥也查了各种反爬虫机制的资料,进行验证和实践,折腾了半天还是没有解决这个问题,也不知道python和java语言的有什么区别了,还是因为被锁定,有点懵。但是宏哥回过头来又用Python语言的处理方法试了一下这个注册页面,仍然可以成功处理,看来不是锁定的问题。但是其不是很稳定啊,后边在运行代码也会弹出选字校验。各位有什么好办法可以留言给宏哥,抱歉了没有帮到大家!

4.1实战过程中遇到的坑及解决办法

1.坑一:报错 message='Chromium distribution 'chrome' is not found at C:\Users\Administrator\AppData\Local\Google\Chrome\Application\chrome.exe ,如下图所示:

解决办法:找到chrome安装路径,将安装文件全部拷贝到代码中报错的路径下即可,如下图所示:

2.坑二:报错类似这样 navigating to "https://passport.ctrip.com/user/reg/home", waiting until "load"。如下图所示:

解决办法:将launch.setSlowMo(50);的时间加长即可。

4.2部分参数详细说明

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

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

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

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

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

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

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

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

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

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

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

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