GVKun编程网logo

等到页面用 Selenium WebDriver for Python 加载(python selenium 等待页面加载)

1

如果您想了解等到页面用SeleniumWebDriverforPython加载的相关知识,那么本文是一篇不可错过的文章,我们将对pythonselenium等待页面加载进行全面详尽的解释,并且为您提供

如果您想了解等到页面用 Selenium WebDriver for Python 加载的相关知识,那么本文是一篇不可错过的文章,我们将对python selenium 等待页面加载进行全面详尽的解释,并且为您提供关于from selenium.webdriver.firefox.options import Options ModuleNotFoundError: No module named 'selenium'、php-webdriver:PHP控制浏览器动作, php web驱动, PHP实现自动化, php webdriver 教程, A php client for webdriver.、Python Selenium Chrome Webdriver、Python Selenium Chrome Webdriver 未安装的有价值的信息。

本文目录一览:

等到页面用 Selenium WebDriver for Python 加载(python selenium 等待页面加载)

等到页面用 Selenium WebDriver for Python 加载(python selenium 等待页面加载)

我想抓取无限滚动实现的页面的所有数据。以下python代码有效。

for i in range(100):    driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")    time.sleep(5)

这意味着每次向下滚动到底部时,我都需要等待 5 秒,这通常足以让页面完成加载新生成的内容。但是,这可能没有时间效率。页面可能会在 5
秒内完成加载新内容。每次向下滚动时,如何检测页面是否完成加载新内容?如果我能检测到这一点,我可以在知道页面完成加载后再次向下滚动以查看更多内容。这样更省时。

答案1

小编典典

默认情况下,将通过方法webdriver等待页面加载。.get()

正如@user227215 所说,您可能正在寻找一些特定元素,您应该使用WebDriverWait等待页面中的元素:

from selenium import webdriverfrom selenium.webdriver.support.ui import WebDriverWaitfrom selenium.webdriver.support import expected_conditions as ECfrom selenium.webdriver.common.by import Byfrom selenium.common.exceptions import TimeoutExceptionbrowser = webdriver.Firefox()browser.get("url")delay = 3 # secondstry:    myElem = WebDriverWait(browser, delay).until(EC.presence_of_element_located((By.ID, ''IdOfMyElement'')))    print "Page is ready!"except TimeoutException:    print "Loading took too much time!"

我用它来检查警报。您可以使用任何其他类型的方法来查找定位器。

编辑1:

我应该提到webdriver默认情况下将等待页面加载。它不等待加载内部框架或 ajax 请求。这意味着当您使用
.get(''url''),您的浏览器将等待页面完全加载,然后转到代码中的下一个命令。但是当您发布 ajax
请求时,webdriver不要等待,您有责任等待适当的时间来加载页面或页面的一部分;所以有一个名为expected_conditions.

from selenium.webdriver.firefox.options import Options ModuleNotFoundError: No module named 'selenium'

from selenium.webdriver.firefox.options import Options ModuleNotFoundError: No module named 'selenium'

如何解决from selenium.webdriver.firefox.options import Options ModuleNotFoundError: No module named ''selenium''?

这是我的问题:当我运行 thos 脚本时,我的 cmd 向我返回一条错误消息,该消息与我的模块的导入有关。

导入脚本:

import logging
import os
import time
from lib2to3.pgen2 import driver

from selenium.webdriver.firefox.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import webdriverwait
from selenium.webdriver.support import expected_conditions as EC
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.options import Options
from selenium import webdriver
from selenium.webdriver.firefox.webdriver import FirefoxProfile
from selenium.webdriver import ActionChains,DesiredCapabilities


# ================================ LOGGER ====================================
import pathlib
import platform
import shutil
import psutil

第一个 cmd 的消息是:

from selenium.webdriver.firefox.options import Options
ModuleNotFoundError: No module named ''selenium''

起初我认为这是我在安装 selenium 后安装的 FireFox 导航器的错误,但最后命令提示符给了我与 Chrome 相同的消息 :O ! 我检查了我的 Pyhton 的版本:“Python 3.9.2”。然后卸载selenium(已经安装了):

pip uninstall selenium
Found existing installation: selenium 3.141.0
Uninstalling selenium-3.141.0:
  Would remove:
    c:\users\w10cp\desktop\stage\venv\lib\site-packages\selenium-3.141.0.dist-info\*
    c:\users\w10cp\desktop\stage\venv\lib\site-packages\selenium\*
Proceed (y/n)? y
  Successfully uninstalled selenium-3.141.0

然后我再次安装它:

pip install selenium
Collecting selenium
  Using cached selenium-3.141.0-py2.py3-none-any.whl (904 kB)
Requirement already satisfied: urllib3 in c:\users\w10cp\desktop\stage\venv\lib\site-packages (from selenium) (1.26.4)
Installing collected packages: selenium
Successfully installed selenium-3.141.0

但那是一样的:

from selenium.webdriver.firefox.options import Options
ModuleNotFoundError: No module named ''selenium''

所以我跑了

C:\Users\w10cp\Desktop\Stage>python
Python 3.9.2 (tags/v3.9.2:1a79785,Feb 19 2021,13:44:55) [MSC v.1928 64 bit (AMD64)] on win32
Type "help","copyright","credits" or "license" for more information.
>>> import selenium

但没有任何变化

File "<stdin>",line 1,in <module>
ModuleNotFoundError: No module named ''selenium''

所以我继续使用 Stack OverFlow 寻找答案。 我成功卸载了 selenium 然后执行:

python -m pip install -U selenium

所以我再次运行我的脚本,结果如​​下:

from webdriver_manager.chrome import ChromeDriverManager
ModuleNotFoundError: No module named ''webdriver_manager''

所以我做了

pip install webdriver_manager

它已成功安装,但它返回相同的错误消息。 如果有人知道我必须做什么,请帮助我。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

php-webdriver:PHP控制浏览器动作, php web驱动, PHP实现自动化, php webdriver 教程, A php client for webdriver.

php-webdriver:PHP控制浏览器动作, php web驱动, PHP实现自动化, php webdriver 教程, A php client for webdriver.

 

项目地址:https://github.com/facebook/php-webdriver

 

一、技术选型

 

php + facebook/webdriver + selenium

Selenium是一套完整的Web应用程序测试系统,它提供了一系列的操作浏览器的 API

webdriver 是 facebook 开发的一套 selenium API 的客户端组件,使用 composer 作为依赖管理工具。

 

二、环境搭建

 

  1. php 的开发环境
  2. webdriver 使用 composer 做依赖管理,所以需要安装 composer
  3. selenium-server 需要 java 运行环境

环境配置自己搞定,很简单,这里就不做赘述了。

 

三、开始使用

 

安装 php-webdriver

1 # 前提是需要安装好 composer.phar 
2 curl -sS https://getcomposer.org/installer | php
3  
4 # 安装library
5 php composer.phar require facebook/webdriver

 

运行 Selenium 服务, 首先你需要到 selenium 官网去下载 selenium-server-standalone-#.jar, 下载地址请狠狠的 戳这里.

或者直接下载最新版 (2018-12-14):selenium-server-standalone-3.9.1

1 java -jar -Dwebdriver.chrome.driver="driver/chromedriver" selenium-server-standalone-x.xx.x.jar -port 4444

需要指定一个 chromedriver(一个阉割版的 chrome 浏览器) ,这里是下载地址 也可以直接下载最新版 (2018-12-14):

chromedriver_mac64 (MAC版)

chromedriver_win32 (Win版)

chromedriver_linux64 (Linux版)

另外:Java 8+ 必须已经安装.

 

然后创建一个会话,并指定你的服务器运行的地址和端口。

1 $host ''http://localhost:4444/wd/hub'';

启动火狐浏览器,前提是你安装了火狐的 Geckodriver

1 $driver = RemoteWebDriver::create($host, DesiredCapabilities::firefox());

或者启动 chrome 浏览器

1 $driver = RemoteWebDriver::create($host, DesiredCapabilities::chrome());

你也可以自定义配置你的浏览器

1 $host ''http://localhost:4444/wd/hub'';
2 $capabilities = DesiredCapabilities::chrome();
3 $driver = RemoteWebDriver::create($host$capabilities, 5000);

更多配置,请参考 这里.

 

设置浏览器窗口

1 $size new WebDriverDimension(1280, 900);
2 $driver->manage()->window()->setSize($size);

$driver->manage()->window() 返回的是一个 WebDriverWindow, 它提供了以下 API

方法名称 方法说明
getPosition(), setPosition() 获取,设置浏览器的位置
getSize(), setSize() 获取,设置浏览器大小
maximize() 最大化窗口

发送请求

1 $driver->get(''http://www.ikeepstudying.com'');

 

操作 DOM 元素

webdriver 主要提供了 2 个 API 来给我们操作 DOM 元素

  1. RemoteWebDriver::findElement(WebDriverBy) 获取单个元素
  2. RemoteWebDriver::findElements(WebDriverBy) 获取元素列表

WebDriverBy 是查询方式对象,提供了下面几个常用的方式

  • WebDriverBy::id($id) 根据 ID 查找元素
  • WebDriverBy::className($className) 根据 class 查找元素
  • WebDriverBy::cssSelector($selctor) 根据通用的 css 选择器查询
  • WebDriverBy::name($name) 根据元素的 name 属性查询
  • WebDriverBy::linkText($text) 根据可见元素的文本锚点查询
  • WebDriverBy::tagName($tagName) 根据元素标签名称查询
  • WebDriverBy::xpath($xpath) 根据 xpath 表达式查询,这个很强大。 不了解什么是 xpath 的请参考我前面的文章 XPath 语法

实例

// id 查询
$input = $driver->findElement(
	 WebDriverBy::id(''key'')
);
//往输入框填入元素
$input->sendKeys(''iPhone 8'');
// xpath 查询
$button = $input->findElement(
    WebDriverBy::xpath("../button[1]")
);
$button->click(); //单击按钮
//获取列表的 a 标签
$links = $driver->findElements(WebDriverBy::cssSelector(".goods-list > .p-img > a"));
$aTags = [];
foreach($links as $value) {
    array_push($aTags, array(
        ''href'' => $value->getAttribute(''href''),
        ''title'' => $value->getAttribute("title")
    ));
}
print_r($aTags);

  cookies 操作

// fetch cookies
$cookies = $driver->manage()->getCookies();
// delete cookies
$driver->manage()->deleteAllCookies();
// add cookies
$driver->manage()->addCookie(array(
    ''name'' => ''cookie_name'',
    ''value'' => ''cookie_value'',
));
$cookies = $driver->manage()->getCookies();

  

键盘操作

  • RemoteKeyboard::sendKeys() 输入内容到当前 focus 的元素
  • RemoteKeyboard::pressKey($key) 按下某个键
  • RemoteKeyboard::releaseKey($key) 释放某个键
$driver->getKeyboard()->sendKeys("登录");
$driver->getKeyboard()->pressKey(WebDriverKeys::SHIFT); //按下 Shift 键
$driver->getKeyboard()->releaseKey(WebDriverKeys::SHIFT);

  

鼠标操作

  • WebDriverMouse::click(WebDriverCoordinates) 单击鼠标
  • WebDriverMouse::doubleClick(WebDriverCoordinates) 双击鼠标
  • WebDriverMouse::mouseDown(WebDriverCoordinates) 触发 mousedown 事件
  • WebDriverMouse::mouseUp(WebDriverCoordinates) 触发 mouseup 事件
  • WebDriverMouse::click(WebDriverCoordinates, $x, $y) 移动鼠标到指定的位置,触发 mousemove 事件

 

注入 JS 代码

  • RemoteWebDriver::executeScript($script, $args) 执行同步js代码
  • RemoteWebDriver::executeAsyncScript($script, $args) 执行异步 js 代码
$driver->executeScript("document.body.scrollTop = 1000; alert(arguments[0])", ["fuck"]);

  截图

$driver->takeScreenshot("test.png");

  

快速开始

Selenium是用于自动化测试工具,它是在Apache许可证2.0许可的开放源代码工具。Selenium是一套工具,它有助于自动化Web应用程序测试。

  • 框架底层使用JavaScript模拟真实用户对浏览器进行操作。测试脚本执行时,浏览器自动按照脚本代码做出点击,输入,打开,验证等操作,就像真实用户所做的一样,从终端用户的角度测试应用程序。
  • 使浏览器兼容性测试自动化成为可能,尽管在不同的浏览器上依然有细微的差别。
  • 使用简单,可使用Java,Python等多种语言编写用例脚本。

 

1.通过composer安装Selenium:

1 composer require facebook/webdriver

2.下载Selenium Server并启动:

1 //到http://www.seleniumhq.org/download/ 下找到Selenium Standalone Server并下载,或到https://chromedriver.storage.googleapis.com/index.html 上面下载。
2 //到命令提示符里启动以下命令(前提需要安装jdk,确保java命令能够运行)
3 java -jar selenium-server-standalone-2.42.2.jar

3. 运行测试代码

另启命令提示符,运行php test.php 命令
示例脚本test.php:

<?php
namespace Facebook\WebDriver;
use Facebook\WebDriver\Remote\DesiredCapabilities;
use Facebook\WebDriver\Remote\RemoteWebDriver;
require_once(''vendor/autoload.php'');

header("Content-Type: text/html; charset=UTF-8");
// start Firefox with 5 second timeout
$waitSeconds = 15;  //需等待加载的时间,一般加载时间在0-15秒,如果超过15秒,报错。
$host = ''http://localhost:4444/wd/hub''; // this is the default
//这里使用的是chrome浏览器进行测试,需到http://www.seleniumhq.org/download/上下载对应的浏览器测试插件
//我这里下载的是win32 Google Chrome Driver 2.25版:https://chromedriver.storage.googleapis.com/index.html?path=2.25/
$capabilities = DesiredCapabilities::chrome();
$driver = RemoteWebDriver::create($host, $capabilities, 5000);
// navigate to ''http://docs.seleniumhq.org/''
$driver->get(''https://www.baidu.com/'');

echo iconv("UTF-8","GB2312",''标题1'').":" . $driver->getTitle() . "\n";	//cmd.exe中文乱码,所以需转码

$driver->findElement(WebDriverBy::id(''kw''))->sendKeys(''wwe'')->submit();

// 等待新的页面加载完成....
$driver->wait($waitSeconds)->until(
    WebDriverExpectedCondition::visibilityOfElementLocated(
        WebDriverBy::partialLinkText(''100shuai'')
    )
);
$driver->findElement(WebDriverBy::partialLinkText(''100shuai''))->sendKeys(''xxx'')->click();	//一般点击链接的时候,担心因为失去焦点而抛异常,则可以先调用一下sendKeys,再click


switchToEndWindow($driver); //切换至最后一个window

// 等待加载....
$driver->wait($waitSeconds)->until(
    WebDriverExpectedCondition::visibilityOfElementLocated(
        WebDriverBy::partialLinkText(''SmackDown收视率创历史新低'')
    )
);
echo iconv("UTF-8","GB2312",''标题2'').":" . $driver->getTitle() . "\n";	//cmd.exe中文乱码,所以需转码

$driver->findElement(WebDriverBy::partialLinkText(''SmackDown收视率创历史新低''))->click();

switchToEndWindow($driver); //切换至最后一个window


// 等待加载....
$driver->wait($waitSeconds)->until(
    WebDriverExpectedCondition::titleContains(''SmackDown收视率创历史新低'')
);
echo iconv("UTF-8","GB2312",''标题3'').":" . $driver->getTitle() . "\n";	//cmd.exe中文乱码,所以需转码


//关闭浏览器
$driver->quit();

//切换至最后一个window
//因为有些网站的链接点击过去带有target="_blank"属性,就新开了一个TAB,而selenium还是定位到老的TAB上,如果要实时定位到新的TAB,则需要调用此方法,切换到最后一个window
function switchToEndWindow($driver){
    
    $arr = $driver->getWindowHandles();
    foreach ($arr as $k=>$v){
        if($k == (count($arr)-1)){
            $driver->switchTo()->window($v);
        }
    }
}

  

元素定位

1. WebDriverBy::id()

通过ID属性定位元素

1 //HTML代码
2 //<input id="kw" name="wd"maxlength="255" autocomplete="off" />
3  
4 <?php
5 $driver = RemoteWebDriver::create($host, DesiredCapabilities::chrome(), 5000);
6 $driver->get(''https://www.baidu.com/'');
7 $element $driver->findElement(WebDriverBy::id(''kw''));
8 ?>

2. WebDriverBy::name()

通过name属性定位元素。如果查找多个,则使用findElements进行定位

01 //HTML代码
02 //<input id="kw" name="wd"maxlength="255" autocomplete="off" />
03  
04 <?php
05 $driver = RemoteWebDriver::create($host, DesiredCapabilities::chrome(), 5000);
06 $driver->get(''https://www.baidu.com/'');
07 $element $driver->findElement(WebDriverBy::name(''wd''));
08 foreach($elements as $elem){    //有时候多个元素时,想找出某个特定元素,可根据attribute或text进行判断过滤
09     echo $elem->getAttribute(''type'');
10     echo $elem->getText();
11 }
12 ?>

3. WebDriverBy::tagName()

通过标签进行定位元素。如果查找多个,则使用findElements进行定位,具体参考WebDriverBy::name()的代码

01 //HTML代码
02 //<input type="hidden" name="rsv_bp" value="0" />
03 //<input id="kw" name="wd"maxlength="255" autocomplete="off" />
04 //.....
05  
06 <?php
07 $driver = RemoteWebDriver::create($host, DesiredCapabilities::chrome(), 5000);
08 $driver->get(''https://www.baidu.com/'');
09 $element $driver->findElement(WebDriverBy::tagName(''input''));
10 ?>

4. WebDriverBy::className()

通过css类进行定位元素。如果查找多个,则使用findElements进行定位,具体参考WebDriverBy::name()的代码

1 //HTML代码
2 //<input id="kw" name="wd"maxlength="255" autocomplete="off" />
3  
4 <?php
5 $driver = RemoteWebDriver::create($host, DesiredCapabilities::chrome(), 5000);
6 $driver->get(''https://www.baidu.com/'');
7 $element $driver->findElement(WebDriverBy::className(''s_ipt''));
8 ?>

5. WebDriverBy::linkText()

通过超文本链接上的文字信息来定位元素。如果查找多个,则使用findElements进行定位,具体参考WebDriverBy::name()的代码

1 //HTML代码
2 //<a href="http://news.baidu.com" name="tj_trnews">新闻</a>
3  
4 <?php
5 $driver = RemoteWebDriver::create($host, DesiredCapabilities::chrome(), 5000);
6 $driver->get(''https://www.baidu.com/'');
7 $element $driver->findElement(WebDriverBy::linkText(''新闻''));
8 ?>

6. WebDriverBy::partialLinkText()

这个方法是上一个方法的扩展。当你不能准确知道超链接上的文本信息或者只想通过一些关键字进行匹配时,可以使用这个方法来通过部分链接文字进行匹配。如果查找多个,则使用findElements进行定位,具体参考WebDriverBy::name()的代码

1 //HTML代码
2 //<a href="http://news.baidu.com" name="tj_trnews">新闻</a>
3  
4 <?php
5 $driver = RemoteWebDriver::create($host, DesiredCapabilities::chrome(), 5000);
6 $driver->get(''https://www.baidu.com/'');
7 $element $driver->findElement(WebDriverBy::partialLinkText(''新''));
8 ?>

7. WebDriverBy::xpath()

这个方法是非常强大的元素查找方式,使用这种方法几乎可以定位到页面上的任意元素。在正式开始使用XPath进行定位前,我们先了解下什么是XPath。XPath是XML Path的简称,由于HTML文档本身就是一个标准的XML页面,所以我们可以使用XPath的语法来定位页面元素。更多详细的定位资料,参考页脚链接地址。

XPath语法如下:

1 <?php
2 $element $driver->findElement(WebDriverBy::xpath("//*[@id=''J_login_form'']/dl/dt/input[@id=''J_password'']"));
3 ?>

8. WebDriverBy::cssSelector()

cssSelector这种元素定位方式跟xpath比较类似,但执行速度较快,而且各种浏览器对它的支持都相当到位,所以功能比较强大。
下面是一些常见的cssSelector的定位方式:
定位id为flrs的div元素,可以写成:#flrs 注:相当于xpath语法的//div[@id=’flrs’]
定位id为flrs下的a元素,可以写成 #flrs > a 注:相当于xpath语法的//div[@id=’flrs’]/a
定位id为flrs下的href属性值为/forexample/about.html的元素,可以写成: #flrs > a[href=”/forexample/about.html”]
如果需要指定多个属性值时,可以逐一加在后面,如#flrs > input[name=”username”][type=”text”]。

明白基本语法后,我们来尝试用cssSelector方式来层级关系定位,代码如下:

1 //HTML代码
2 //<a href="http://news.baidu.com" name="tj_trnews">新闻</a>
3  
4 <?php
5 $element $driver->findElement(WebDriverBy::cssSelector("#J_login_form>dl>dt>input[id=''J_password'']"));
6 ?>

cssSelector还有一个用处是定位使用了复合样式表的元素,之前在第4种方式className里面提到过。现在我们就来看看如何通过cssSelector来引用到第4种方式中提到的那个button。button代码如下:

1 //HTML代码
2 //<button id="J_sidebar_login"type="submit">登录</button>
3  
4 <?php
5 $element $driver->findElement(WebDriverBy::cssSelector("button.btn.btn_big.btn_submit"));
6 ?>

此外,cssSelector还有一些高级用法,如果熟练后可以更加方便地帮助我们定位元素,如我们可以利用^用于匹配一个前缀,$用于匹配一个后缀,*用于匹配任意字符。例如:

匹配一个有id属性,并且id属性是以”id_prefix_”开头的超链接元素:a[id^=’id_prefix_’]
匹配一个有id属性,并且id属性是以”_id_sufix”结尾的超链接元素:a[id$=’_id_sufix’]
匹配一个有id属性,并且id属性中包含”id_pattern”字符的超链接元素:a[id*=’id_pattern’]

9. 判断定位的元素是否存在

selenium找元素时,如果超出timeout时间后,还未找到元素,则会报异常,我们则可以利用这样的方式进行判断元素是否存在。不过这种方式对于及时性要求不高的情况下使用,如果要求及时性的话,建议还是获取到page source后,用htmlparser或正则判断即可。

01 <?php
02  
03 if(isElementExsit($driver, WebDriverBy::linkText(''新闻''))){
04     echo ''找到元素啦'';
05 }else{
06     echo ''没有找到元素'';
07 }
08  
09 /**
10  * 判断元素是否存在
11  * @param WebDriver $driver
12  * @param WebDriverBy $locator
13  */
14 function isElementExsit($driver,$locator){
15     try {
16         $nextbtn $driver->findElement($locator);
17         return true;
18     catch (\Exception $e) {
19         echo ''element is not found!'';
20         return false;
21     }
22 }
23 ?>

 

元素操作

1.输入框

1 $element $driver->findElement(WebDriverBy::id(''wd''));
2 $element->sendKeys("wwe");   //在输入框中输入内容
3 $element->clear();   //将输入框清空
4 $element->getAttribute(''value''); //获取输入框的文本内容

2.单选框

1 $radio $driver->findElement(WebDriverBy::id(''BookMode''));
2 $radio->click(); //选择某个单选项
3 $radio->isSelected();    //判断某个单选项是否已经被选择

3.多选框

1 $checkbox $driver->findElement(WebDriverBy::id(''myCheckbox''));
2 $checkbox->click();  //选择某选项
3 $checkbox->isSelected(); //判断该选项是否已经被选择
4 $checkbox->isEnabled();  //判断是否enable

4.下拉框

下拉框是我们最常见的一种页面元素,对于一般的元素,我们只需要一次就定位,但下拉框里的内容需要进行两次定位,先定位到下拉框,再定位到下拉框内里的选项。

1 $select $driver->findElement(WebDriverBy::id(''myselect''));
2 $select->findElement(WebDriverBy::xpath("//option[@value=''100'']"))->click();  //找到值为100的选项进行选中

5.按钮

1 $btn $driver->findElement(WebDriverBy::id(''btn''));
2 $btn->click();   //点击按钮
3 $btn->isEnabled();   //判断是否enable

6.文件上传

1 $upload $driver->findElement(WebDriverBy::id(''img-upload''));
2 $filePath "C:\test\\uploadfile\\media_ads\\test.jpg";
3 $upload->sendKeys($filePath);

7.指定元素点击

因为有时候因为种种原因(如元素上有蒙版层或者因为一些浮动的div导致坐标变化或者不可点击),而不能使用$ele.click()时,采用通用的方式,就是用JS执行点击事件。而且点击事件是可被监听的,可在元素上写onclick事件进行监听。

01 //用webdriver获取对象,再进行JS操作
02 $ele $driver->findElement(WebDriverBy::id(''haha''));
03 $driver->executeScript("arguments[0].click();",[$ele]);
04  
05 //用JS获取对象进行操作
06 $js = <<<js
07 var ele = document.getElementById(''haha'');
08 ele.click();
09 js;
10 $driver->executeScript($js);

8.滚动到指定元素

用JS的方式滚动到指定的元素。

1 $ele $driver->findElement(WebDriverBy::id(''haha2''));
2 $driver->executeScript("arguments[0].scrollIntoView();",[$ele]);

9.移动到指定元素

移动的时候,鼠标不会真正移动,但实际上已移动,这个可以在haha2元素上写一个onmouseover事件进行监听即可测试。

1 $ele $driver->findElement(WebDriverBy::id(''haha2''));
2 $driver->getMouse()->mouseMove($ele->getCoordinates());

 

元素等待

 

明确的等待

明确的等待是指在代码进行下一步操作之前等待某一个条件的发生。最不好的情况是使用sleep()去设置一段确认的时间去等待。但为什么说最不好呢?因为一个元素的加载时间有长有短,你在设置sleep的时间之前要自己把握长短,太短容易超时,太长浪费时间。selenium webdriver提供了一些方法帮助我们等待正好需要等待的时间,比如以下例子中我们设置的最长等待时间为15秒。

01 <?php
02 namespace Facebook\WebDriver;
03 use Facebook\WebDriver\Remote\DesiredCapabilities;
04 use Facebook\WebDriver\Remote\RemoteWebDriver;
05 require_once(''vendor/autoload.php'');
06  
07 header("Content-Type: text/html; charset=UTF-8");
08 // start Firefox with 5 second timeout
09 $host ''http://localhost:4444/wd/hub''; // this is the default
10 $waitSeconds = 15;  //需等待加载的时间,一般加载时间在0-15秒,如果超过15秒,报错。
11 $capabilities = DesiredCapabilities::chrome();
12 $driver = RemoteWebDriver::create($host$capabilities, 5000);
13 $driver->get(''https://www.baidu.com/'');
14  
15 //由于下拉框是通过点击“搜索设置”按钮触发JS动态生成的DOM,所以这里使用Wait for new element to appear方式,不然直接调用查找元素会报错,说找不到元素
16 $driver->wait($waitSeconds)->until(
17     WebDriverExpectedCondition::visibilityOfElementLocated(
18         WebDriverBy::id(''kw'')
19     )
20 );
21 $driver->findElement(WebDriverBy::id(''kw''))->sendKeys(''wwe'');
22 echo ''done!'';
23 //关闭浏览器
24 //$driver->quit();
25  
26 ?>

 

隐性等待

隐性等待是指当要查找元素,而这个元素没有马上出现时,告诉WebDriver查询Dom一定时间。默认值是0,但是设置之后,这个时间将在WebDriver对象实例整个生命周期都起作用。上面的代码就变成了这样:

01 <?php
02 namespace Facebook\WebDriver;
03 use Facebook\WebDriver\Remote\DesiredCapabilities;
04 use Facebook\WebDriver\Remote\RemoteWebDriver;
05 require_once(''vendor/autoload.php'');
06  
07 header("Content-Type: text/html; charset=UTF-8");
08 // start Firefox with 5 second timeout
09 $host ''http://localhost:4444/wd/hub''; // this is the default
10 $capabilities = DesiredCapabilities::chrome();
11 $driver = RemoteWebDriver::create($host$capabilities, 5000);
12 $driver->manage()->timeouts()->implicitlyWait(15);    //隐性设置15秒
13 $driver->get(''https://www.baidu.com/'');
14  
15 $driver->findElement(WebDriverBy::id(''kw''))->sendKeys(''wwe'');
16 echo ''done!'';
17  
18 //关闭浏览器
19 //$driver->quit();
20  
21 ?>

 

JS调用

01 <?php
02 namespace Facebook\WebDriver;
03 use Facebook\WebDriver\Remote\DesiredCapabilities;
04 use Facebook\WebDriver\Remote\RemoteWebDriver;
05 require_once(''vendor/autoload.php'');
06  
07 header("Content-Type: text/html; charset=UTF-8");
08  
09  
10 // start Firefox with 5 second timeout
11 $host ''http://localhost:4444/wd/hub''; // this is the default
12 $capabilities = DesiredCapabilities::chrome();
13 $driver = RemoteWebDriver::create($host$capabilities, 5000);
14 $driver->get(''https://www.baidu.com/'');
15  
16 $element $driver->findElement(WebDriverBy::className(''s_ipt''));
17  
18 $js = <<<js
19     document.getElementById("kw").style.border = ''2px solid red'';
20     var button = document.getElementById("su");
21     button.setAttribute(''type'',''button'');
22     button.setAttribute(''onclick'',''document.getElementById("kw").style.border = "2px solid blue";alert("hello,dear wangkun!");'');
23 js;
24 $driver->executeScript($js);
25 echo ''done!'';
26  
27 //关闭浏览器
28 //$driver->quit();
29  
30 ?>

 

验证码识别

有些网站打开后,有验证码需要填写,而我们又不能直接获取该验证码的远程地址,然后下载,这样的话就相当于又请求了一次,那么验证码又被更新了,就达不到我们识别验证码的效果。
而我们的方案是通过网页截图,然后找到验证码的具体位置,然后再截图方式把验证码图片获取到。废话不多说,直接开始!

示例脚本:

01 <?php
02 namespace Facebook\WebDriver;
03 use Facebook\WebDriver\Remote\DesiredCapabilities;
04 use Facebook\WebDriver\Remote\RemoteWebDriver;
05 require_once(''vendor/autoload.php'');
06  
07 header("Content-Type: text/html; charset=UTF-8");
08 const vcodeDst = ''f://vcode.png'';   //验证码存放地址
09  
10 // start Firefox with 5 second timeout
11 $host ''http://localhost:4444/wd/hub''; // this is the default
12 $capabilities = DesiredCapabilities::chrome();
13 $driver = RemoteWebDriver::create($host$capabilities, 5000);
14 $driver->get(''http://www.yimuhe.com/'');
15  
16 $driver->manage()->window()->maximize();    //将浏览器最大化
17 $driver->takeScreenshot(vcodeDst);  //截取当前网页,该网页有我们需要的验证码
18 $element $driver->findElement(WebDriverBy::id(''vcode_img''));
19 generateVcodeIMG($element->getLocation(), $element->getSize(),vcodeDst);
20  
21 echo ''done!'';
22  
23 //关闭浏览器
24 $driver->quit();
25  
26 /**
27  * 生成验证码图片
28  * @param $location 验证码x,y轴坐标
29  * @param $size 验证码的长宽
30  */
31 function generateVcodeIMG($location,$size,$src_img){
32     $width $size->getWidth();
33     $height $size->getHeight();
34     $x $location->getX();
35     $y $location->getY();
36      
37     $src = imagecreatefrompng($src_img);
38     $dst = imagecreatetruecolor($width,$height);
39     imagecopyresampled($dst,$src,0,0,$x,$y,$width,$height,$width,$height);
40     imagejpeg($dst,$src_img);
41     chmod($src_img,0777);
42     imagedestroy($src);
43     imagedestroy($dst);
44 }
45 ?>

备注:当我们已经把正确的验证码图片下载到了本地后,不管是用自己写的OCR程序进行识别还是用第三方程序进行识别都可以,这个就比较简单了,就不在这里进行陈述。
这里推荐一个比较准确的第三方验证码识别的程序,集成一下就可以了。
https://www.juhe.cn/docs/api/id/60/aid/344

 

frame与弹窗的控制

 

对于web应用,经常会出现框架(frame) 或窗口(window)的应用,这也就给我们的定位带来了一个难题。有时候我们定位一个元素,定位器没有问题,但一直定位不了,这时候就要检查这个元素是否在一个frame中,seelnium webdriver 提供了这样的方法,可以很轻松的来解决这个问题。

  • $driver->switchTo()->frame(“id”)
  • $driver->switchTo()->window(“id”)
  • $driver->switchTo()->alert()

 

frame示例脚本

01 <?php
02 namespace Facebook\WebDriver;
03 use Facebook\WebDriver\Remote\DesiredCapabilities;
04 use Facebook\WebDriver\Remote\RemoteWebDriver;
05 require_once(''vendor/autoload.php'');
06  
07 header("Content-Type: text/html; charset=UTF-8");
08  
09  
10 // start Firefox with 5 second timeout
11 $host ''http://localhost:4444/wd/hub''; // this is the default
12 $capabilities = DesiredCapabilities::chrome();
13 $driver = RemoteWebDriver::create($host$capabilities, 5000);
14 $driver->manage()->timeouts()->implicitlyWait(15);    //隐性设置15秒
15 $driver->get(''https://v.qq.com/x/cover/e7hi6lep1yc51ca.html?vid=h0018p9ihom'');
16  
17 echo $driver->getCurrentURL().''\r\n'';
18  
19  
20 //将页面滚动条拖到底部
21 //因为这个页面默认打开的时候,"评论区"的iframe没有渲染到DOM里,腾讯做的处理是拖动到底部的时候用JS动态渲染,所以我们需要控制浏览器滚动至底部
22 $js "window.scrollBy(0,100000000);";
23 $driver->executeScript($js);
24 sleep(3);
25  
26 #再找到其下面的 iframe(id=commentIframe)
27 $driver->switchTo()->frame("commentIframe");
28 $str $driver->getPageSource();
29  
30 //将获取到的影评数据保存再本地,再测试是否正确。
31 $myfile fopen("d://newfile.html""w"or die("Unable to open file!");
32 fwrite($myfile$str);
33 fclose($myfile);
34  
35 echo ''done!'';
36  
37 //关闭浏览器
38 $driver->quit();
39  
40 ?>

alert示例脚本

1 <?php
2 //~~~以上代码省略...
3 $driver->switchTo()->alert()->accept();    //获取到confim alert,并且点击同意
4 $driver->switchTo()->alert()->dismiss();   //取消
5 $driver->switchTo()->alert()->getText();   //获取alert弹出的提示内容
6 ?>

我们以百度的页面为例来演示一下功能。
1.点击百度的设置
2.选择”每天显示多少条”的下拉框 (这个顺便把“元素操作”文章中的“select”元素章节也演示了)
3.点击保存设置按钮:会弹出一个alert弹窗
4.执行点击alert的确定按钮
5.试一下搜索的结果是否变化,操作完毕

01 <?php
02 namespace Facebook\WebDriver;
03 use Facebook\WebDriver\Remote\DesiredCapabilities;
04 use Facebook\WebDriver\Remote\RemoteWebDriver;
05 require_once(''vendor/autoload.php'');
06  
07 header("Content-Type: text/html; charset=UTF-8");
08  
09  
10 // start Firefox with 5 second timeout
11 $host ''http://localhost:4444/wd/hub''; // this is the default
12 $waitSeconds = 15;  //需等待加载的时间,一般加载时间在0-15秒,如果超过15秒,报错。
13 $capabilities = DesiredCapabilities::chrome();
14 $driver = RemoteWebDriver::create($host$capabilities, 5000);
15 $driver->get(''https://www.baidu.com/'');
16  
17  
18 $driver->findElement(WebDriverBy::linkText(''设置''))->click();
19  
20 $driver->findElement(WebDriverBy::linkText(''搜索设置''))->click();
21  
22 $warpper $driver->findElement(WebDriverBy::id(''wrapper''));
23  
24  
25 //由于下拉框是通过点击“搜索设置”按钮触发JS动态生成的DOM,所以这里使用Wait for new element to appear方式,不然直接调用查找元素会报错,说找不到元素
26 $driver->wait($waitSeconds)->until(
27     WebDriverExpectedCondition::visibilityOfElementLocated(
28         WebDriverBy::id(''nr'')
29     )
30 );
31  
32 $selectDom $warpper->findElement(WebDriverBy::id(''nr''));
33 $select new WebDriverSelect($selectDom);
34 $select->selectByValue(10);
35  
36 //由于下拉框是通过点击“搜索设置”按钮触发JS动态生成的DOM,所以这里使用Wait for new element to appear方式,不然直接调用查找元素会报错,说找不到元素
37 $driver->wait($waitSeconds)->until(
38     WebDriverExpectedCondition::visibilityOfElementLocated(
39         WebDriverBy::linkText(''保存设置'')
40     )
41 );
42  
43 $driver->findElement(WebDriverBy::linkText(''保存设置''))->click();
44  
45 sleep(2);
46  
47 $driver->switchTo()->alert()->accept();
48  
49 $driver->findElement(WebDriverBy::id("kw"))->sendKeys(''wwe'');
50 $driver->findElement(WebDriverBy::id("su"))->click();
51  
52 echo ''done!'';
53  
54 //关闭浏览器
55 //$driver->quit();
56  
57 ?>

window弹窗 示例脚本

1 //$driver->switchTo()->window("id"),用法与 frame 相同。

 

AJAX分页数据获取

有时候有些列表页使用的是滚动条到最底部才加载下一页的数据,这个时候就需要用到selenium来操作这样的数据。我们拿letv的分页来做测试。

01 <?php
02 namespace Facebook\WebDriver;
03 use Facebook\WebDriver\Remote\DesiredCapabilities;
04 use Facebook\WebDriver\Remote\RemoteWebDriver;
05 require_once(''vendor/autoload.php'');
06  
07 header("Content-Type: text/html; charset=UTF-8");
08 // start Firefox with 5 second timeout
09 $host ''http://localhost:4444/wd/hub''; // this is the default
10 $capabilities = DesiredCapabilities::chrome();
11 $driver = RemoteWebDriver::create($host$capabilities, 5000);
12 $driver->manage()->timeouts()->implicitlyWait(15);    //隐性设置15秒
13 $driver->get(''http://list.le.com/listn/c1_t-1_a50071_y-1_s1_lg-1_ph-1_md_o4_d1_p.html'');
14  
15 //翻一页
16 js = "window.scrollTo(0,document.body.scrollHeight)"    //滚动至底部
17 //$js = "window.scrollBy(0,100000000);";  //也可以把值设大一点,达到底部的效果
18 $driver->executeScript($js);
19  
20 echo ''sleep...'';
21 sleep(6);
22  
23 //再翻一页
24 js = "window.scrollTo(0,document.body.scrollHeight)";
25 $driver->executeScript($js);
26  
27 echo ''sleep...'';
28 sleep(6);
29  
30 //再翻一页
31 js = "window.scrollTo(0,document.body.scrollHeight)";
32 $driver->executeScript($js);
33  
34 echo ''done!'';
35  
36 //关闭浏览器
37 //$driver->quit();
38  
39 ?>

 

PhantomJS

用浏览器驱动的方式,很方便我们在测试阶段调试代码正确性,但是由于浏览器要启动,解析DOM、JS、下载图片等,使得程序跑起来的效率并不高,这个时候我们就需要用到Phantomjs,以后台的形式运行程序,大大的提升运行的性能。

 

1.安装Phantomjs

到http://phantomjs.org/download.html 上面去下载对应的版本,我这里下载的是windows版本的。将解压包中的phantomjs.exe放到PHP程序根目录,或将该exe加入到本机的环境变量中都行。

 

2.使用Phantomjs

拿的是“验证码识别”那篇文章的代码,只改了一处,$capabilities = DesiredCapabilities::phantomjs();这一行。
运行后,可以看到“验证码识别”程序不再启动chrome浏览器,而是后台执行,速度也快了很多。程序顺利跑出了我们想要的结果~ 大家可以休息一下咯~

01 <?php
02 namespace Facebook\WebDriver;
03 use Facebook\WebDriver\Remote\DesiredCapabilities;
04 use Facebook\WebDriver\Remote\RemoteWebDriver;
05 require_once(''vendor/autoload.php'');
06  
07 header("Content-Type: text/html; charset=UTF-8");
08 const vcodeDst = ''f://vcode.png'';   //验证码存放地址
09  
10 // start Firefox with 5 second timeout
11 $host ''http://localhost:4444/wd/hub''; // this is the default
12 $capabilities = DesiredCapabilities::phantomjs();
13 $driver = RemoteWebDriver::create($host$capabilities, 5000);
14 $driver->get(''http://www.yimuhe.com/'');
15  
16 $driver->manage()->window()->maximize();    //将浏览器最大化
17 $driver->takeScreenshot(vcodeDst);  //截取当前网页,该网页有我们需要的验证码
18 $element $driver->findElement(WebDriverBy::id(''vcode_img''));
19 generateVcodeIMG($element->getLocation(), $element->getSize(),vcodeDst);
20  
21 echo ''done!'';
22  
23 //关闭浏览器
24 $driver->quit();
25  
26 /**
27  * 生成验证码图片
28  * @param $location 验证码x,y轴坐标
29  * @param $size 验证码的长宽
30  */
31 function generateVcodeIMG($location,$size,$src_img){
32     $width $size->getWidth();
33     $height $size->getHeight();
34     $x $location->getX();
35     $y $location->getY();
36  
37     $src = imagecreatefrompng($src_img);
38     $dst = imagecreatetruecolor($width,$height);
39     imagecopyresampled($dst,$src,0,0,$x,$y,$width,$height,$width,$height);
40     imagejpeg($dst,$src_img);
41     chmod($src_img,0777);
42     imagedestroy($src);
43     imagedestroy($dst);
44 }
45 ?>

 

屏蔽图片

共有两种方法,一种设置chrome配置,一种直接使用插件达到相应的目的。其中使用插件来屏蔽图片可转到“使用扩展插件”章节。这里就介绍chrome配置。

 

1. 查看chrome支持的浏览器属性

chrome driver的官方文档( https://sites.google.com/a/chromium.org/chromedriver/capabilities ),可以看到,chrome driver可以支持的自定义属性

php-webdriver:PHP控制浏览器动作, php web驱动, PHP实现自动化, A php client for webdriver.php-webdriver:PHP控制浏览器动作, php web驱动, PHP实现自动化, A php client for webdriver.

 

2. 查看本地配置的参数值

可以使用自己的chrome浏览器进行配置,配置好了后,查看“Preferences文件”里的值就可以了。一般路径都为“用户文件夹\AppData\Local\Google\Chrome\User Data\Default”。

php-webdriver:PHP控制浏览器动作, php web驱动, PHP实现自动化, A php client for webdriver.php-webdriver:PHP控制浏览器动作, php web驱动, PHP实现自动化, A php client for webdriver. php-webdriver:PHP控制浏览器动作, php web驱动, PHP实现自动化, A php client for webdriver.php-webdriver:PHP控制浏览器动作, php web驱动, PHP实现自动化, A php client for webdriver. php-webdriver:PHP控制浏览器动作, php web驱动, PHP实现自动化, A php client for webdriver.php-webdriver:PHP控制浏览器动作, php web驱动, PHP实现自动化, A php client for webdriver.

 

3. 代码DEMO

找到了屏蔽图片对应的参数后,我们就可以进行测试了

01 $host ''http://localhost:4444/wd/hub''; // this is the default
02 $capabilities = DesiredCapabilities::chrome();
03 $options new ChromeOptions();
04 $value = [''profile.managed_default_content_settings.images''=>2];
05 $options->setExperimentalOption(''prefs''$value);
06 $capabilities->setCapability(ChromeOptions::CAPABILITY, $options);
07  
08 $driver = RemoteWebDriver::create($host$capabilities, 5000);
09 $driver->manage()->timeouts()->implicitlyWait(15);    //隐性设置15秒
10  
11 $driver->get(''http://www.baidu.com/'');
12  
13 echo ''done'';

 

4. 换个思路,变得更简洁

上面提到的都是设置具体的参数,而要找到对应设置的参数比较繁杂,当如果不想那么麻烦时候,完全可以在已有的chrome浏览器先设置好,然后把“用户文件夹\AppData\Local\Google\Chrome\User Data”加载到自己的应用中。

01 $host ''http://localhost:4444/wd/hub''; // this is the default
02 $capabilities = DesiredCapabilities::chrome();
03 $options new ChromeOptions();
04 $options->addArguments(["--user-data-dir=d:/xampp/test/User Data"]);
05 $capabilities->setCapability(ChromeOptions::CAPABILITY, $options);
06  
07 $driver = RemoteWebDriver::create($host$capabilities, 5000);
08 $driver->manage()->timeouts()->implicitlyWait(15);    //隐性设置15秒
09  
10 $driver->get(''http://www.baidu.com/'');
11  
12 echo ''done'';

 

总结:这里虽然只是介绍的屏蔽图片,但是同理的chrome其他设置也可以用这样的方式进行,如禁用JS等等之类的。

 

使用扩展插件

有时候我们需要使用浏览器的扩展插件来帮助我们达到某种特定的效果,比如“Block Image”插件可使得selenium使用过程中不显示图片,从而加快访问的速度和性能。再比如使用“adsafe”插件可使得访问网站的时候禁用相应的广告以及弹窗广告等。

这里我们使用”Block Image”插件的来展示下selenium怎么加载插件。这里使用的是chrome driver方式进行测试,其他浏览器的测试代码请自行百度。

1.下载Block Image插件

到http://www.cnplugins.com/ 上面搜索Block Image,下载下来,存放到自己的程序根目录。

2.代码测试

01 <?php
02 namespace Facebook\WebDriver;
03 use Facebook\WebDriver\Remote\DesiredCapabilities;
04 use Facebook\WebDriver\Remote\RemoteWebDriver;
05 use Facebook\WebDriver\Chrome\ChromeOptions;
06 require_once(''vendor/autoload.php'');
07  
08 header("Content-Type: text/html; charset=UTF-8");
09  
10 // start Firefox with 5 second timeout
11 $host ''http://localhost:4444/wd/hub''; // this is the default
12 $capabilities = DesiredCapabilities::chrome();
13 $options new ChromeOptions();
14 $options->addExtensions([''Block-image.crx'']); //这一句则为加载我们下载好的插件
15 $capabilities->setCapability(ChromeOptions::CAPABILITY, $options);
16 $driver = RemoteWebDriver::create($host$capabilities, 15000);
17 $driver->manage()->timeouts()->implicitlyWait(15); //隐性设置15秒
18 $driver->get(''http://www.tudou.com/list/ach4a-2b-2c-2d-2e-2f1689g-2h-2i-2j-2k-2l-2m-2n-2sort1.html'');

 

代理设置

有时候我们需要修改浏览器的一些User Agent信息或代理IP,从而达到更好的兼容性测试。这里我们就用一个在线UserAgent分析工具进行测试。

1.修改User Agent

Chrome 示例
这里提供user-agent大全供参考http://www.cnblogs.com/hykun/p/Ua.html

01 <?php
02 namespace Facebook\WebDriver;
03 use Facebook\WebDriver\Remote\DesiredCapabilities;
04 use Facebook\WebDriver\Remote\RemoteWebDriver;
05 use Facebook\WebDriver\Chrome\ChromeOptions;
06 require_once(''vendor/autoload.php'');
07  
08 header("Content-Type: text/html; charset=UTF-8");
09  
10 // start Firefox with 5 second timeout
11 $host ''http://localhost:4444/wd/hub''; // this is the default
12 $capabilities = DesiredCapabilities::chrome();
13 $useragent ''Mozilla/5.0 (Linux; U; Android 2.3.7; en-us; Nexus One Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1'';
14 $options new ChromeOptions();
15 $options->addArguments(["user-agent={$useragent}"]);
16 $capabilities->setCapability(ChromeOptions::CAPABILITY, $options);
17  
18 $driver = RemoteWebDriver::create($host$capabilities, 5000);
19 $driver->manage()->timeouts()->implicitlyWait(15);    //隐性设置15秒
20 $driver->get(''http://www.atool.org/useragent.php'');
21 var_dump($capabilities->getCapability(ChromeOptions::CAPABILITY));
22 echo ''done!'';
23  
24 //关闭浏览器
25 //$driver->quit();
26 ?>

Phantomjs 示例

01 <?php
02 namespace Facebook\WebDriver;
03 use Facebook\WebDriver\Remote\DesiredCapabilities;
04 use Facebook\WebDriver\Remote\RemoteWebDriver;
05 use Facebook\WebDriver\Chrome\ChromeOptions;
06 require_once(''vendor/autoload.php'');
07  
08 header("Content-Type: text/html; charset=UTF-8");
09  
10 // start Firefox with 5 second timeout
11 $host ''http://localhost:4444/wd/hub''; // this is the default
12 $capabilities = DesiredCapabilities::phantomjs();
13 $useragent ''Mozilla/5.0 (Linux; U; Android 2.3.7; en-us; Nexus One Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1'';
14 $capabilities->setCapability("phantomjs.page.settings.userAgent"$useragent);
15  
16 $driver = RemoteWebDriver::create($host$capabilities, 5000);
17 $driver->manage()->timeouts()->implicitlyWait(15);    //隐性设置15秒
18 $driver->get(''http://www.atool.org/useragent.php'');
19 echo $driver->findElement(WebDriverBy::id(''ua_code''))->getAttribute(''value'');
20 echo ''done!'';
21  
22 //关闭浏览器
23 $driver->quit();
24 ?>

 

2.修改代理IP

01 <?php
02 namespace Facebook\WebDriver;
03 use Facebook\WebDriver\Remote\RemoteWebDriver;
04 use Facebook\WebDriver\Remote\WebDriverCapabilityType;
05 require_once(''vendor/autoload.php'');
06  
07 header("Content-Type: text/html; charset=UTF-8");
08 $host ''http://localhost:4444/wd/hub''; // this is the default
09 $ip ''115.225.2.3:8998'';   //设置代理IP
10 $capabilities array(WebDriverCapabilityType::BROWSER_NAME => ''chrome'',
11                         WebDriverCapabilityType::PROXY => array(''proxyType'' => ''manual'',
12                         ''httpProxy'' => $ip''sslProxy'' => $ip));
13  
14 $driver = RemoteWebDriver::create($host$capabilities, 5000);
15 $driver->manage()->timeouts()->implicitlyWait(15);    //隐性设置15秒
16 $driver->get(''https://www.baidu.com/'');
17 $driver->findElement(WebDriverBy::id(''kw''))->sendKeys(''ip'');
18 $driver->findElement(WebDriverBy::id(''su''))->click();
19 echo ''done!'';
20 //关闭浏览器
21 //$driver->quit();
22  
23 ?>

 

使用总结

使用selenium时会遇到很多的坑,这里分享一些经验给大家。

 

1.wait ~ until的使用

要勤使用wait~until,由于我们打开的网页有时候会比较慢时,查找调用某个元素时就比较容易报NoSuchElementException异常。或者有时候一些JS是动态生成的,也需要用到wait~until,不然也会报错。

 

2.switchToEndWindow勤使用

switchToEndWindow是我们自定义的一个方法,由于我们使用selenium访问某个网页,然后又点击了其中一个链接,谁知道这个链接是否含有target=”_blank”呢。做爬虫类程序尤为如此。所以我们增加一个方法,每次点击了某个链接跳转后,执行一下switchToEndWindow方法。

01 <?php
02 //切换至最后一个window
03 function switchToEndWindow($driver){
04  
05     $arr $driver->getWindowHandles();
06     foreach ($arr as $k=>$v){
07         if($k == (count($arr)-1)){
08             $driver->switchTo()->window($v);
09         }
10     }
11 }
12 ?>

 

3.异常处理

使用selenium过程中,会碰到各种意想不到的报错。比如做爬虫过程中,都要用try包含起来处理异常,这样可以防止一旦异常报错后,终止了程序的执行。那么在测试的每个节点的健康状态,可在数据库中记录查询。

 

4.定位异常解决

元素在网页第一次加载后,就会确定他的坐标,当我们进行了某种操作,改变了宽度或高度,则很容易引起相关元素的坐标改变,从而报错。
报错信息:Element is not clickable at point (284, 11).
解决保存就是在调用click或submit方式之前先调用sendKeys方法,让其重绘坐标

1 $elemA->sendKeys(''xxx'')->click();
2 $elemB->sendKeys(''xxx'')->submit();

有时候,以上使用sendKeys方式还是没办法解决问题时,则很可能是因为网页中含有浮动DIV,导致各个元素定位变化了。
这个时候只需要找到那个浮动的DIV,隐藏掉就可以了。

1 $js = <<<js
2     var nav = document.getElementsByClassName("nav_m");
3     nav[0].style.display = ''none'';
4 js;
5 $driver->executeScript($js);

如果以上两种方式结合都还有问题的情况下,就建议用JS来解决。

01 //设置屏幕滚动到当前元素
02 $elems $driver->findElements(WebDriverBy::className(''n''));
03 foreach ($elems as $elem){
04     if(CommonUtil::contain($elem->getText(), ''下一页'')){
05         $elem->sendKeys(''xxx''); //设置焦点
06     }
07 }
08                  
09                  
10 $js = <<<js
11     var next = document.getElementsByClassName(''n'');
12     for (i = 0; i < next.length; i++) {
13         if(next[i].innerHTML == ''下一页&gt;''){
14             //next[i].click();
15             next[i].style.backgroundColor = "red";
16         }
17     }
18 js;
19  
20 $driver->executeScript($js);    //JS执行点击下一页

 

5.执行时间的设置

使用自动化测试或爬虫程序,往往程序执行的时间会比较长。为了防止timeout,我们需要设置如下

1 set_time_limit(0);
2 ignore_user_abort(true);

 

下载资料:
1.http://selenium-release.storage.googleapis.com/index.html (selenium 下载地址)
2.https://chromedriver.storage.googleapis.com/index.html (chrome driver 下载地址)
3.http://phantomjs.org/download.html (PhantomJS Driver 下载地址)
4.http://www.cnbeta.com/articles/soft/563605.htm (chrome 下载地址,建议使用这个版本或者以下版本,其他最新版本,浏览器识别了是否为测试软件,对于个别用途的软件需要注意,如果仅仅是为了做测试,那就无所谓了。)
5.http://blog.csdn.net/huilan_same/article/details/51896672 (chromedriver.exe版本对应的chrome版本)

 

参考文档:
1.https://github.com/facebook/php-webdriver (里面有example.php以及 tests文件下的案例文档共参考)
2.https://github.com/facebook/php-webdriver/wiki 快速开始教程
3.http://facebook.github.io/php-webdriver/namespaces/default.html API文档
4.http://www.yiibai.com/selenium/ 易百教程
6.https://github.com/chibimagic/WebDriver-PHP/
7.https://code.google.com/archive/p/php-webdriver-bindings/
8.https://github.com/Element-34/php-webdriver
9.https://github.com/Nearsoft/php-selenium-client
10.http://pan.baidu.com/s/1eR31pM6 selenium_webdriver(python)第一版.pdf

 

 

元素定位

1. WebDriverBy::id()

通过ID属性定位元素

1 //HTML代码
2 //<input id="kw" name="wd"maxlength="255" autocomplete="off" />
3  
4 <?php
5 $driver = RemoteWebDriver::create($host, DesiredCapabilities::chrome(), 5000);
6 $driver->get(''https://www.baidu.com/'');
7 $element $driver->findElement(WebDriverBy::id(''kw''));
8 ?>

2. WebDriverBy::name()

通过name属性定位元素。如果查找多个,则使用findElements进行定位

01 //HTML代码
02 //<input id="kw" name="wd"maxlength="255" autocomplete="off" />
03  
04 <?php
05 $driver = RemoteWebDriver::create($host, DesiredCapabilities::chrome(), 5000);
06 $driver->get(''https://www.baidu.com/'');
07 $element $driver->findElement(WebDriverBy::name(''wd''));
08 foreach($elements as $elem){    //有时候多个元素时,想找出某个特定元素,可根据attribute或text进行判断过滤
09     echo $elem->getAttribute(''type'');
10     echo $elem->getText();
11 }
12 ?>

3. WebDriverBy::tagName()

通过标签进行定位元素。如果查找多个,则使用findElements进行定位,具体参考WebDriverBy::name()的代码

01 //HTML代码
02 //<input type="hidden" name="rsv_bp" value="0" />
03 //<input id="kw" name="wd"maxlength="255" autocomplete="off" />
04 //.....
05  
06 <?php
07 $driver = RemoteWebDriver::create($host, DesiredCapabilities::chrome(), 5000);
08 $driver->get(''https://www.baidu.com/'');
09 $element $driver->findElement(WebDriverBy::tagName(''input''));
10 ?>

4. WebDriverBy::className()

通过css类进行定位元素。如果查找多个,则使用findElements进行定位,具体参考WebDriverBy::name()的代码

1 //HTML代码
2 //<input id="kw" name="wd"maxlength="255" autocomplete="off" />
3  
4 <?php
5 $driver = RemoteWebDriver::create($host, DesiredCapabilities::chrome(), 5000);
6 $driver->get(''https://www.baidu.com/'');
7 $element $driver->findElement(WebDriverBy::className(''s_ipt''));
8 ?>

5. WebDriverBy::linkText()

通过超文本链接上的文字信息来定位元素。如果查找多个,则使用findElements进行定位,具体参考WebDriverBy::name()的代码

1 //HTML代码
2 //<a href="http://news.baidu.com" name="tj_trnews">新闻</a>
3  
4 <?php
5 $driver = RemoteWebDriver::create($host, DesiredCapabilities::chrome(), 5000);
6 $driver->get(''https://www.baidu.com/'');
7 $element $driver->findElement(WebDriverBy::linkText(''新闻''));
8 ?>

6. WebDriverBy::partialLinkText()

这个方法是上一个方法的扩展。当你不能准确知道超链接上的文本信息或者只想通过一些关键字进行匹配时,可以使用这个方法来通过部分链接文字进行匹配。如果查找多个,则使用findElements进行定位,具体参考WebDriverBy::name()的代码

1 //HTML代码
2 //<a href="http://news.baidu.com" name="tj_trnews">新闻</a>
3  
4 <?php
5 $driver = RemoteWebDriver::create($host, DesiredCapabilities::chrome(), 5000);
6 $driver->get(''https://www.baidu.com/'');
7 $element $driver->findElement(WebDriverBy::partialLinkText(''新''));
8 ?>

7. WebDriverBy::xpath()

这个方法是非常强大的元素查找方式,使用这种方法几乎可以定位到页面上的任意元素。在正式开始使用XPath进行定位前,我们先了解下什么是XPath。XPath是XML Path的简称,由于HTML文档本身就是一个标准的XML页面,所以我们可以使用XPath的语法来定位页面元素。更多详细的定位资料,参考页脚链接地址。

XPath语法如下:

view source
 
1 <?php
2 $element $driver->findElement(WebDriverBy::xpath("//*[@id=''J_login_form'']/dl/dt/input[@id=''J_password'']"));
3 ?>

Python Selenium Chrome Webdriver

Python Selenium Chrome Webdriver

我开始自动化无聊的东西书,并且尝试通过python打开chrome网络浏览器。我已经安装了selenium和

我试图运行此文件:

from selenium import webdriverfrom selenium.webdriver.common.by import Byfrom selenium.webdriver.common.keys import Keysbrowser = webdriver.Chrome()browser.get(''https://automatetheboringstuff.com'')

但是正因为如此,我得到这个错误:

Traceback (most recent call last):   File "C:\Program Files   (x86)\Python36-32\lib\site-packages\selenium\webdriver\common\service.py", line 74, in start     stdout=self.log_file, stderr=self.log_file)   File "C:\Program Files (x86)\Python36-32\lib\subprocess.py", line 707, in __init__     restore_signals, start_new_session)   File "C:\Program Files (x86)\Python36-32\lib\subprocess.py", line 990, in _execute_child     startupinfo) FileNotFoundError: [WinError 2] The system cannot find the file specified

在处理上述异常期间,发生了另一个异常:

Traceback (most recent call last):   File "C:/Program Files(x86)/Python36-32/test.py", line 5, in <module>    browser = webdriver.Chrome()   File "C:\Program Files (x86)\Python36-32\lib\site-packages\selenium\webdriver\chrome\webdriver.py",line 62, in __init__   self.service.start()   File "C:\Program Files (x86)\Python36-32\lib\site-packages\selenium\webdriver\common\service.py",line 81, in start   os.path.basename(self.path), self.start_error_message) selenium.common.exceptions.WebDriverException: Message: ''chromedriver''  executable needs to be in PATH. Please seehttps://sites.google.com/a/chromium.org/chromedriver/home

答案1

小编典典

您需要 指定chromedriver所在的路径

  1. 从此处下载适用于所需平台的chromedriver。

  2. 将chromedriver放置在系统路径或代码所在的位置。

  3. 如果不使用系统路径,请链接您的chromedriver.exe(对于非Windows用户,简称为chromedriver):

    browser = webdriver.Chrome(executable_path=r"C:\path\to\chromedriver.exe")

(设置executable_path为chromedriver所在的位置。)

如果您在系统路径上放置了chromedriver,则可以通过以下操作来实现快捷方式:

browser = webdriver.Chrome()

  1. 如果您在基于Unix的操作系统上运行,则可能需要在下载chromedriver后更新chromedriver的权限,以使其可执行:

chmod +x chromedriver

Python Selenium Chrome Webdriver 未安装

Python Selenium Chrome Webdriver 未安装

你需要告诉webdriver的路径:

webdriver.chrome(executable_path=*path*,options=options)

但是 driver2 = webdriver.Chrome(ChromeDriverManager().install()) 创建一个新的 selenium 实例。

driver = webdriver.Chrome(ChromeDriverManager().install(),options=options)

应该适用于您的用例 - 代码的第一行不需要

请注意,'headless' 前面也需要'--'。

完整代码:

options = selenium.webdriver.ChromeOptions()
#options.add_argument('--headless')
#could also do options.headless = True
options.add_argument('--window-size=1920x1080')
driver = webdriver.Chrome(ChromeDriverManager().install(),options=options)
driver.get('enterwebsite.ext')
#do other stuff
,

driver = webdriver.Chrome(driver2,options=options)

您正在发送一个 WebDriver 对象作为位置参数。

https://www.selenium.dev/selenium/docs/api/py/webdriver_chrome/selenium.webdriver.chrome.webdriver.html#module-selenium.webdriver.chrome.webdriver

WebDriver 的第一个参数是可执行路径。

,

试试看:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from webdriver_manager.chrome import ChromeDriverManager

options = Options()
options.add_argument('--headless')
options.add_argument('--window-size=1920,1080')
driver = webdriver.Chrome(ChromeDriverManager().install(),options=options)

driver.get('https://google.com')

driver.quit()

当您将参数选项传递给 webdriver 时,将其设置在初始化上方并将其放入 chrome() 中,如下所示:

options = Options()
options.add_argument('--headless')
options.add_argument('--window-size=1920,options=options)

并最终初始化驱动程序

今天关于等到页面用 Selenium WebDriver for Python 加载python selenium 等待页面加载的介绍到此结束,谢谢您的阅读,有关from selenium.webdriver.firefox.options import Options ModuleNotFoundError: No module named 'selenium'、php-webdriver:PHP控制浏览器动作, php web驱动, PHP实现自动化, php webdriver 教程, A php client for webdriver.、Python Selenium Chrome Webdriver、Python Selenium Chrome Webdriver 未安装等更多相关知识的信息可以在本站进行查询。

本文标签: