SpiderFlow平台v0.5.0之引入selenium插件

引入selenium插件

安装错误处理

1、无法找到二进制文件

报错信息:

复制代码
org.openqa.selenium.WebDriverException: Cannot find firefox binary in PATH. Make sure firefox is installed. OS appears to be: LINUX
Build info: version: 'unknown', revision: 'unknown', time: 'unknown'
System info: host: 'zyldev01', ip: '10.0.3.190', os.name: 'Linux', os.arch: 'amd64', os.version: '3.10.0-1160.el7.x86_64', java.version: '1.8.0_181'
Driver info: driver.version: FirefoxDriver
    at org.openqa.selenium.firefox.FirefoxBinary.<init>(FirefoxBinary.java:116)
    at java.util.Optional.orElseGet(Optional.java:267)
    at org.openqa.selenium.firefox.FirefoxOptions.getBinary(FirefoxOptions.java:218)
    at org.openqa.selenium.firefox.FirefoxDriver.toExecutor(FirefoxDriver.java:155)
    at org.openqa.selenium.firefox.FirefoxDriver.<init>(FirefoxDriver.java:120)
    at org.spiderflow.selenium.driver.FireFoxDriverProvider.getWebDriver(FireFoxDriverProvider.java:87)
    at org.spiderflow.selenium.executor.shape.SeleniumExecutor.execute(SeleniumExecutor.java:111)
    at org.spiderflow.core.Spider.lambda$executeNode$4(Spider.java:285)
    at com.alibaba.ttl.TtlRunnable.run(TtlRunnable.java:59)
    at org.spiderflow.concurrent.SpiderFlowThreadPoolExecutor$SubThreadPoolExecutor.lambda$submitAsync$0(SpiderFlowThreadPoolExecutor.java:152)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

该错误信息表明 WebDriver 无法找到 Firefox 浏览器的二进制文件,原因可能是 Firefox 浏览器没有正确安装,或者它没有添加到 PATH 环境变量中。解决此问题,可以通过以下几个步骤进行:

1)确保 Firefox 已安装

首先,请确认 Firefox 浏览器已正确安装在系统上。可以通过以下命令检查:

复制代码
firefox --version

如果系统提示 command not found 或类似错误,表示 Firefox 没有安装。你可以通过以下命令安装 Firefox:

对于基于 Debian 的系统(如 Ubuntu)

复制代码
sudo apt update sudo apt install firefox

对于基于 RHEL/CentOS 的系统

复制代码
sudo yum install firefox

2)设置 Firefox 路径

如果 Firefox 已安装,但 WebDriver 仍然提示找不到 Firefox 二进制文件,则需要确保 Firefox 的安装路径添加到 PATH 环境变量中。

  • 查找 Firefox 安装路径

    运行以下命令来查找 Firefox 的安装路径:

    复制代码
    which firefox

    该命令会返回 Firefox 的完整路径,例如:/usr/bin/firefox

  • 设置 Firefox 路径

    可以通过设置环境变量 webdriver.firefox.bin 来指定 Firefox 的二进制文件路径。在 Selenium 测试脚本中,使用如下代码:

    复制代码
    System.setProperty("webdriver.firefox.bin", "/usr/bin/firefox");

    或者,如果你使用的是 FirefoxOptions

    python 复制代码
    FirefoxOptions options = new FirefoxOptions(); 
    
    options.setBinary("/usr/bin/firefox"); 
    
    WebDriver driver = new FirefoxDriver(options);

    其中 /usr/bin/firefox 替换为实际的 Firefox 安装路径。

3.)确保 FirefoxDriver 与 Firefox 版本匹配

确认你下载的 geckodriver(Firefox 的 WebDriver)与系统中安装的 Firefox 版本兼容。你可以通过以下命令检查 Firefox 的版本:

python 复制代码
firefox --version

然后下载与 Firefox 版本匹配的 geckodriver,可以从 GeckoDriver Releases 页面下载。

4) 添加 Firefox 路径到 PATH

如果你希望 Firefox 能在任何地方通过命令行访问,确保 Firefox 路径添加到系统的 PATH 环境变量中。你可以通过以下命令将其添加到 .bashrc.bash_profile 文件中:

python 复制代码
echo "export PATH=$PATH:/usr/bin" >> ~/.bashrc 
source ~/.bashrc

如果 Firefox 安装在其他路径,只需修改 /usr/bin 为实际路径。

5)确认 geckodriver 已正确安装

geckodriver 必须在 PATH 中,或者你可以手动设置其路径。你可以通过以下命令确认 geckodriver 是否已安装并正确配置:

python 复制代码
geckodriver --version

如果没有安装 geckodriver,可以从以下地址下载适合你操作系统的版本:

GeckoDriver 下载页面

确保 geckodriver 已添加到 PATH 中,或者在代码中显式设置其路径,例如:

python 复制代码
System.setProperty("webdriver.gecko.driver", "/path/to/geckodriver");

总结

  • 确保 Firefox 已安装且可执行。
  • 检查 Firefox 的路径并确保在环境变量 PATH 中。
  • 下载与 Firefox 版本兼容的 geckodriver 并配置正确的路径。

按照这些步骤,你应该能够解决 Cannot find firefox binary in PATH 的问题。如果问题依然存在,可能需要重新检查 Firefox 和 geckodriver 的安装路径配置。

2、浏览器启动失败

报错:

python 复制代码
org.openqa.selenium.WebDriverException: Process unexpectedly closed with status 1

org.openqa.selenium.WebDriverException: Process unexpectedly closed with status 1 是 Selenium 中常见的错误之一。这个错误通常发生在 WebDriver 启动浏览器时,浏览器驱动(例如 chromedrivergeckodriver)未能正确启动,或者浏览器本身遇到了启动问题。错误的状态码 1 表示程序退出时发生了异常。

以下是一些常见的原因以及对应的解决方案:

1)浏览器和驱动不匹配

浏览器版本和 WebDriver 版本必须匹配。如果你使用的是较新的浏览器版本,但驱动程序版本较旧,或者反之,都可能导致 WebDriver 启动失败。

解决方法

  • 检查浏览器版本:查看你的浏览器(例如 Chrome 或 Firefox)版本。
  • 下载兼容的 WebDriver 版本:根据你的浏览器版本下载与之匹配的 WebDriver。

比如:

  • 对于 Chrome,你可以访问 chromedriver download 来下载适合你 Chrome 版本的 chromedriver
  • 对于 Firefox,你可以访问 geckodriver releases 来下载与 Firefox 版本匹配的 geckodriver

2)驱动文件不可执行或权限问题

如果驱动程序文件没有正确的执行权限,Selenium 启动时会遇到问题。

解决方法: 你需要确保驱动程序文件具有可执行权限。在 Linux 或 macOS 系统中,可以运行以下命令来设置文件的执行权限:

python 复制代码
chmod +x /path/to/your/driver

3) 缺少必要的依赖库(特别是在 Linux 上)

对于 Linux 系统,某些浏览器驱动(尤其是 chromedriver)可能需要依赖特定的库。如果这些库缺失,WebDriver 启动会失败。

解决方法: 你可以通过以下命令安装缺少的依赖库(例如,在 Ubuntu 上):

python 复制代码
sudo apt-get install libnss3 libgdk-pixbuf2.0-0 libx11-xcb1

这些是 Chromium 和 chromedriver 通常需要的库。

4)浏览器启动异常

有时浏览器本身的问题(例如设置了某些配置)也会导致 WebDriver 启动失败。

还有就是如果你的爬虫平台布置在服务器上,你本地要调用浏览器的话,可能由于驱动差异会调用不起来

解决方法

  • 确保没有后台的浏览器实例运行。
  • 尝试使用无头模式(headless mode)启动浏览器,特别是在 CI/CD 环境或没有图形界面的服务器上。

可以设置以下参数来启动无头模式:

浏览器有头和无头模式了解

浏览器的"无头模式"(Headless Mode)和"有头模式"(Headed Mode)是指浏览器是否以图形用户界面(GUI)形式显示出来的两种运行方式。这两种模式的主要区别在于是否显示浏览器窗口。

1. 有头模式(Headed Mode)

  • 定义:有头模式是浏览器的常规运行模式,指的是浏览器启动时会弹出一个可视的窗口,用户可以看到浏览器的图形界面并与之交互。
  • 特点
    • 浏览器窗口可见,用户可以直接操作。
    • 页面加载、渲染和交互都可以通过图形界面直观地进行。
    • 适用于需要与页面直接交互的场景(例如手动测试、用户实际使用的场景等)。
  • 使用场景
    • 自动化测试时调试,开发人员希望通过可视化界面查看页面元素的变化。
    • 需要与浏览器进行实时交互的场景。

2. 无头模式(Headless Mode)

  • 定义:无头模式是指浏览器启动时不显示图形界面,而是在后台运行,所有的渲染和操作都是在无图形界面的环境下进行的。
  • 特点
    • 浏览器没有窗口显示,也不能与其交互。
    • 通常更快速,因为不需要渲染图形界面,减少了系统资源的占用。
    • 非常适合自动化测试和大规模的网页抓取。
    • 能够在没有显示器或图形界面的环境中运行(如服务器环境、Docker 容器等)。
  • 使用场景
    • 自动化测试:当需要在后台执行大量的浏览器测试时,无头模式可以提高执行速度。
    • 网页抓取(Web Scraping):爬虫程序通常会用无头模式来抓取网页内容,而不需要浏览器界面。
    • CI/CD 流水线:在持续集成或自动化部署中,通常采用无头模式来运行自动化测试,以提高效率。

无头模式的优点:

  1. 性能更高:由于不需要渲染和显示浏览器界面,系统资源占用较少,运行速度较快。
  2. 适用于无图形界面环境:在服务器、虚拟机、容器(如 Docker)等没有图形界面的环境中,可以通过无头模式运行浏览器。
  3. 更适合批量任务:例如自动化测试、网页抓取等任务,因为这些任务通常不需要人工交互,且需要高效处理大量页面。

无头模式的缺点:

  1. 无法直接查看页面:在调试时如果出现问题,无法通过浏览器的界面进行直观检查。
  2. 可能存在兼容性问题:某些功能或页面的行为在有头模式和无头模式下可能有所不同,尤其是与页面渲染和交互有关的复杂功能。

总结

  • 有头模式:浏览器正常显示图形界面,适用于需要人工交互或调试的场景。
  • 无头模式:浏览器不显示图形界面,适用于后台任务,如自动化测试、网页抓取等,通常可以提高性能和效率。

你可以根据实际需求来选择使用哪种模式。如果是自动化测试且不需要查看页面细节,推荐使用无头模式;如果是调试或需要人工交互,则应该使用有头模式。

节点说明

  • 页面加载超时时间,单位为毫秒
  • 元素获取超时时间,单位为毫秒
  • URL:起始地址
  • 节点执行完毕后,会产生resp 类型为SeleniumResponse的变量

SeleniumResponse 属性

字段名称 字段类型 字段描述
html String 页面HTML
json JSONObject/JSONArray 内容转json结果
cookies Map<String,String> cookies
url String 当前页面的URL
title String 当前页面的标题

SeleniumResponse 方法

switchTo

参数名 描述 可否为空
index/iframeName/WebElement 要切换的iframe
python 复制代码
${resp.switchTo(index)}

TIP

返回值类型:SeleniumResponse

switchToDefault

切换至默认,即从iframe里切换回来

python 复制代码
${resp.switchToDefault()}

selector

参数名 描述 可否为空
cssSelector 要获取的cssSelector

TIP

返回值类型:WebElement

  • 获取页面上的第一个div
python 复制代码
${resp.selector('div')}

selectors

参数名 描述 可否为空
cssSelector 要获取的cssSelector

TIP

返回值类型:WebElements

  • 获取页面上的所有div
python 复制代码
${resp.selectors('div')}

xpath

参数名 描述 可否为空
xpath 要获取的xpath

TIP

返回值类型:WebElement

  • 获取页面上的第一个div
python 复制代码
${resp.xpath('//div')}

xpaths

参数名 描述 可否为空
xpath 要获取的xpath

TIP

返回值类型:WebElements

  • 获取页面上的所有div
python 复制代码
${resp.xpaths('//div')}

executeScript

参数名 描述 可否为空
script js脚本
List<Object> 参数

TIP

返回值类型:Object

  • 执行js
javascript 复制代码
${resp.executeScript('return "hello spider-flow-" + arguments[0];',['selenium'])}

quit

  • 退出浏览器
javascript 复制代码
${resp.quit()}

toUrl

参数名 描述 可否为空
url 要跳转的url
  • 跳转到百度
javascript 复制代码
${resp.toUrl('https://www.baidu.com')}

loadCookies

  • 将cookie加载至cookieContext中,以便后续自动管理cookie
javascript 复制代码
${resp.loadCookies()}

WebElement 方法

html

TIP

返回值类型:String

  • 获取节点的html
javascript 复制代码
${elementVar.html()}

text

TIP

返回值类型:String

  • 获取节点的text
javascript 复制代码
${elementVar.text()}

attr

TIP

返回值类型:String

  • 获取节点的href属性
javascript 复制代码
${elementVar.attr('href')}

selector

参数名 描述 可否为空
cssSelector 要获取的cssSelector

TIP

返回值类型:WebElement

  • 获取该节点下的第一个div
javascript 复制代码
${elementVar.selector('div')}

selectors

参数名 描述 可否为空
cssSelector 要获取的cssSelector

TIP

返回值类型:WebElements

  • 获取获取该节点下的所有div
javascript 复制代码
${elementVar.selectors('div')}

xpath

参数名 描述 可否为空
xpath 要获取的xpath

TIP

返回值类型:WebElement

  • 获取获取该节点下的第一个div
复制代码
  1. ${elementVar.xpath('//div')}

xpaths

参数名 描述 可否为空
xpath 要获取的xpath

TIP

返回值类型:WebElements

  • 获取获取该节点下的所有div
javascript 复制代码
​​​​​​​${elementVar.xpaths('//div')}

screenshot

TIP

返回值类型:byte[]

  • 对该节点进行截图

    ${elementVar.screenshot()}

click

TIP

返回值类型:WebElement

  • 对该节点进行点击

    ${elementVar.click()}

sendKeys

TIP

返回值类型:WebElement

  • 对该节点进行模拟按键

    ${elementVar.sendKeys('hello spider-flow')}

clickAndHold

release

move

参数名 描述 可否为空
offset_x offset x
offset_y offset y

TIP

在该节点上模拟鼠标移动,当offset_x和offset_y为空时,则模拟鼠标移动到该节点上

doubleClick

pause

perform

TIP

以上6个方法是配套使用,调用perform时才是真正执行动作

  • 模拟鼠标移动到该节点上,等待500ms在点击,等待500ms在移动,最后释放(模拟拖拽滑块条)

    ${elementVar.move().pause(500).clickAndHold().pause(500).move(200,0).release().perform()}

WebElements 方法

html

TIP

返回值类型:List<String>

  • 获取节点的html

    ${elementsVar.html()}

text

TIP

返回值类型:List<String>

  • 获取节点的text

    ${elementsVar.text()}

attr

TIP

返回值类型:List<String>

  • 获取节点的href属性

    ${elementsVar.attr('href')}

selector

参数名 描述 可否为空
cssSelector 要获取的cssSelector

TIP

返回值类型:WebElement

  • 获取该节点下的第一个div

    ${elementsVar.selector('div')}

selectors

参数名 描述 可否为空
cssSelector 要获取的cssSelector

TIP

返回值类型:WebElements

  • 获取获取该节点下的所有div

    ${elementsVar.selectors('div')}

xpath

参数名 描述 可否为空
xpath 要获取的xpath

TIP

返回值类型:WebElement

  • 获取获取该节点下的第一个div

    ${elementsVar.xpath('//div')}

xpaths

参数名 描述 可否为空
xpath 要获取的xpath

TIP

返回值类型:WebElements

  • 获取获取该节点下的所有div

    ${elementsVar.xpaths('//div')}

相关推荐
niuniu_6669 小时前
简单的自动化场景(以 Chrome 浏览器 为例)
运维·chrome·python·selenium·测试工具·自动化·安全性测试
suimeng61 天前
ChromeDriver的常用方法
java·selenium
niuniu_6661 天前
Selenium 性能测试指南
selenium·测试工具·单元测试·测试·安全性测试
莓事哒1 天前
selenium和pytessarct提取古诗文网的验证码(python爬虫)
爬虫·python·selenium·测试工具·pycharm
suimeng61 天前
基本元素定位(findElement方法)
java·selenium
mywpython1 天前
mac 最新的chrome版本配置selenium的方式
chrome·python·selenium·macos
软件测试曦曦1 天前
如何使用Python自动化测试工具Selenium进行网页自动化?
自动化测试·软件测试·python·功能测试·测试工具·程序人生·自动化
freejackman1 天前
Selenium框架——Web自动化测试
python·selenium·测试
互联网杂货铺1 天前
黑盒测试、白盒测试、集成测试和系统测试的区别与联系
自动化测试·软件测试·python·功能测试·测试工具·单元测试·集成测试
Feng.Lee2 天前
聊一聊缓存如何进行测试
功能测试·测试工具·缓存