python怎么定位富文框textarea的元素我用xpath定位包找不到元素

python怎么定位富文框textarea的元素我用xpath定位包找不到元素,第1张

selenium,一个有效的自动化测试工具,我主要介绍下关于如何封装WebDriver,为一个比较轻松上手的自动化测试埋下铺垫

工具/原料

selenium-server-standalone-2390jar软件包

方法/步骤

先了解下什么是WebDriver

熟悉WebDriver的关于JAVA的一些API的使用

介绍一个火狐的插件firepath

我做的自动化测试是在火狐上运行的,因为我找到一个对于自动化测试比较有帮助的插件,那就是firepath,具体用法,就是先安装该插件,它会在firebug那么调试的窗口最右边出现。firepath截图和firepath安装后的截图如下所示。(优点:点哪个元素,哪个元素的xpath路径立马显示,看图吧)

自己封装的WebDriver的API方法

package comqiangdata;

import javautilIterator;

import javautilList;

import javautilSet;

import orgopenqaseleniumBy;

import orgopenqaseleniumNoSuchElementException;

import orgopenqaseleniumWebDriver;

import orgopenqaseleniumWebElement;

/

WebDriver帮助类

/

public class WebDriverUtil {

/

写在前面的话:

我写的这个WebDriver帮助类法仅仅针对于xpath访问的

为什么这么写呢?有两点理由

其一:xpath获取方便,我用的是firefox浏览器,只要用firepath这个插件,我们就可以正确的定位到每一个节点,并且firepath支持查询功能,值得大家使用

其二:使用统一的xpath,给编码带来了一定的规范

/

/

没有验证码的的登录

@param wd WebDriver对象

@param unameXpath 用户名的xpath路径

@param uname 用户名

@param pwdXpath 密码xpath路径

@param pwdValue 密码

@param loginBtnXpath 登录按钮xpath

/

public static void login(WebDriver wd,String url,String unameXpath,String uname,String pwdXpath,String pwd,String loginBtnXpath){

wdget(url);

inputs(wd,unameXpath,uname);

inputs(wd,pwdXpath, pwd);

click(wd,loginBtnXpath);

}

/

登录可能放在一个frame里了:我是因为遇到过,所以才加了个方法的

@param wd WebDriver对象

@param unameXpath 用户名的xpath路径

@param uname 用户名

@param pwdXpath 密码xpath路径

@param pwdValue 密码

@param loginBtnXpath 登录按钮xpath

@param frame 第几个框架

/

public static void loginFrame(WebDriver wd,String url,String unameXpath,String uname,String pwdXpath,String pwd,String loginBtnXpath,int frame){

wdget(url);

wdswitchTo()frame(frame);

inputs(wd,unameXpath,uname);

inputs(wd,pwdXpath, pwd);

click(wd,loginBtnXpath);

}

/

有验证码的登录

@param wd WebDriver对象

@param unameXpath 用户名的xpath路径

@param uname 用户名

@param pwdXpath 密码xpath路径

@param pwdValue 密码

@param loginBtnXpath 登录按钮xpath

@param seconds 输入验证码的间隔

/

public static void loginVerify(WebDriver wd,String url,String unameXpath,String uname,String pwdXpath,String pwd,String loginBtnXpath,int seconds){

wdget(url);

inputs(wd,unameXpath,uname);

inputs(wd,pwdXpath, pwd);

try {

Threadsleep(seconds1000); //这段时间内请输入验证码

} catch (InterruptedException e) {

eprintStackTrace();

}

click(wd,loginBtnXpath);

}

/

获取页面单个元素

@param wd WebDriver对象

@param xpath 目标节点的xpath

@return

/

public static WebElement getElement(WebDriver wd,String xpath){

return wdfindElement(Byxpath(xpath));

}

/

获取页面的一组元素

@param wd WebDriver对象

@param xpath 目标节点的xpath

@return

/

public static List<WebElement> getElements(WebDriver wd,String xpath){

return wdfindElements(Byxpath(xpath));

}

/

获取元素节点的文本值

@param wd WebDriver对象

@param xpath 目标节点的xpath

@return

/

public static String getText(WebDriver wd,String xpath){

return wdfindElement(Byxpath(xpath))getText();

}

/

获取元素节点的文本值

@param wd WebDriver对象

@param xpath 目标节点的xpath

@return 没有找到该元素时会有个提示,并且不会报错,建议使用

/

public static String getExistText(WebDriver wd,String xpath){

if(isExist(wd, xpath)){

return getText(wd, xpath);

}

return "-1";

}

/

获取元素节点的属性值

@param wd WebDriver对象

@param xpath 目标节点的xpath

@attribute 要获取目标节点的哪个属性

@return

/

public static String getAttribute(WebDriver wd,String xpath,String attribute){

return wdfindElement(Byxpath(xpath))getAttribute(attribute);

}

/

点击节点

@param wd WebDriver对象

@param xpath 目标节点的xpath

@return

/

public static void click(WebDriver wd,String xpath){

wdfindElement(Byxpath(xpath))click();

}

/

输入文本

@param wd WebDriver对象

@param xpath 目标节点的xpath

@return

/

public static void inputs(WebDriver wd,String xpath,String value){

wdfindElement(Byxpath(xpath))sendKeys(value);

}

/

判断是否选中

@param wd WebDriver对象

@param xpath 目标节点的xpath

@return

/

public static boolean isChecked(WebDriver wd,String xpath){

return wdfindElement(Byxpath(xpath))isSelected();

}

/

判断是否可用

@param wd WebDriver对象

@param xpath 目标节点的xpath

@return

/

public static boolean isEnabled(WebDriver wd,String xpath){

return wdfindElement(Byxpath(xpath))isEnabled();

}

/

判断是否存在元素

@param wd WebDriver对象

@param xpath 目标节点的xpath

@return

/

public static boolean isExist(WebDriver wd,String xpath){

try{

wdfindElement(Byxpath(xpath));

return true;

}catch (NoSuchElementException e) {

return false;

}

}

/

选中复选框,其实和点击一样,只是重新起了个名字

@param wd WebDriver对象

@param xpath 目标节点的xpath

/

public static void check(WebDriver wd,String xpath){

click(wd, xpath);

}

/

点击那种隐藏的下拉框

@param wd WebDriver对象

@param xpath1 事件源节点的xpath

@param xpath2 目标节点的xpath

/

public static void clickHidden(WebDriver wd,String xpath1,String xpath2){

click(wd, xpath1);

click(wd, xpath2);

}

/

获取隐藏的文本,原理同上

@param wd WebDriver对象

@param xpath1 事件源节点的xpath

@param xpath2 目标节点的xpath

/

public static void getHiddenText(WebDriver wd,String xpath1,String xpath2){

click(wd, xpath1);

getText(wd, xpath2);

}

/

获取隐藏节点的属性值

@param wd WebDriver对象

@param xpath1 事件源节点的xpath

@param xpath2 目标节点的xpath

@param attribute 要获取目标节点的哪个属性

/

public static String getHiddenAttribute(WebDriver wd,String xpath1,String xpath2,String attribute){

click(wd, xpath1);

return getAttribute(wd, xpath2, attribute);

}

/

切换窗口

@param wd WebDriver对象

@param title 要切换窗口的标题

/

public static void changeWindow(WebDriver wd,String title){

String current = wdgetWindowHandle();

Set<String> all = wdgetWindowHandles();

Iterator<String> iterator = alliterator();

while (iteratorhasNext()) {

String handle = iteratornext();

if(handleequals(current)){

continue;

}

else{

wdswitchTo()window(handle);

if(wdgetTitle()contains(title)){

Systemoutprintln("窗口成功跳转");

break;

}

else{

continue;

}

}

}

}

}

5

个人小结

以上基于WebDriver简单的封装在一定程度上可以减少代码量,封装得太少,看到的你根据自己的需要进行扩充吧,我个人特点是喜欢封装一切可以复用的代码,以便达到高效率的编码,并不是说会编码就够了,多总结总结还是会让自己的编码路不会走的那么崎岖些

获取标签内容

使用elementattribute()方法获取dom元素的内容,如:

dr = driverfind_element_by_id('tooltip')

drget_attribute('data-original-title') #获取tooltip的内容

drtext #获取该链接的text

获取标签属性

link=drfind_element_by_id('tooltip')

linkvalue_of_css_property('color') #获取tooltip的CSS属性color的属性值

linkfind_element_by_tag_name('h3')value_of_css_property('font') #获取h3的CSS属性font的属性值

获取标签状态

是否显示:使用elementis_displayed()方法

是否存在:使用find_element_by_xxx()方法,捕获其抛出的异常, 如果存在异常的话则可以确定该元素不存在

text_field=drfind_element_by_name('user')is_enabled()

#直接用elementis_enabled()方法判断button,返回值为true,因为button是使用CSS方法判断是否有效这并不是真正的方法,需要判断其class中是否有值为disabled来判断是否真正处于disabled的状态

drfind_element_by_class_name('btn')is_enabled()

是否被选中:一般判断表单元素,如radio或checkbox是否被选中,使用elementis_selected()方法

radiois_selected() #判断是否被选中

try:

drfind_element_by_id('none')

except:

print 'element does not exist'

是否有效:即是否为灰化状态,使用elementis_enabled()状态

print text_fieldis_displayed() #判断是否显示

使用时先安装 lxml 包

开始使用 #

和beautifulsoup类似,首先我们需要得到一个文档树

把文本转换成一个文档树对象

from lxml import etreeif __name__ == '__main__':doc='''

把文件转换成一个文档树对象

fromlxmlimportetree# 读取外部文件 indexhtmlhtml = etreeparse('/indexhtml')result = etreetostring(html, pretty_print=True)#pretty_print=True 会格式化输出print(result)

均会打印出文档内容

节点、元素、属性、内容 #

xpath 的思想是通过 路径表达 去寻找节点。节点包括元素,属性,和内容

元素举例

html --->div --->

这里我们可以看到,这里的元素和html中的标签一个意思。单独的元素是无法表达一个路径的,所以单独的元素不能独立使用

路径表达式 #

/  根节点,节点分隔符,//  任意位置  当前节点  父级节点@  属性

通配符 #

  任意元素@  任意属性node()  任意子节点(元素,属性,内容)

谓语 #

使用中括号来限定元素,称为谓语

//a[n] n为大于零的整数,代表子元素排在第n个位置的 元素//a[last()]  last()  代表子元素排在最后个位置的 元素//a[last()-]  和上面同理,代表倒数第二个//a[position()<3] 位置序号小于3,也就是前两个,这里我们可以看出xpath中的序列是从1开始//a[@href]    拥有href的 元素//a[@href='内置很多函数。更多函数查看 >

Python 中可以进行网页解析的库有很多,常见的有 BeautifulSoup 和 lxml 等。在网上玩爬虫的文章通常都是介绍 BeautifulSoup 这个库,我平常也是常用这个库,最近用 Xpath 用得比较多,使用 BeautifulSoup 就不大习惯,很久之前就知道 Reitz 大神出了一个叫 Requests-HTML 的库,一直没有兴趣看,这回可算歹着机会用一下了。

使用 pip install requests-html 安装,上手和 Reitz 的其他库一样,轻松简单:

这个库是在 requests 库上实现的,r 得到的结果是 Response 对象下面的一个子类,多个一个 html 的属性。所以 requests 库的响应对象可以进行什么 *** 作,这个 r 也都可以。如果需要解析网页,直接获取响应对象的 html 属性:

不得不膜拜 Reitz 大神太会组装技术了。实际上 HTMLSession 是继承自 requestsSession 这个核心类,然后将 requestsSession 类里的 requests 方法改写,返回自己的一个 HTMLResponse 对象,这个类又是继承自 requestsResponse,只是多加了一个 _from_response 的方法来构造实例:

之后在 HTMLResponse 里定义属性方法 html,就可以通过 html 属性访问了,实现也就是组装 PyQuery 来干。核心的解析类也大多是使用 PyQuery 和 lxml 来做解析,简化了名称,挺讨巧的。

元素定位可以选择两种方式:

方法名非常简单,符合 Python 优雅的风格,这里不妨对这两种方式简单的说明:

定位到元素以后势必要获取元素里面的内容和属性相关数据,获取文本:

获取元素的属性:

还可以通过模式来匹配对应的内容:

这个功能看起来比较鸡肋,可以深入研究优化一下,说不定能在 github 上混个提交。

除了一些基础 *** 作,这个库还提供了一些人性化的 *** 作。比如一键获取网页的所有超链接,这对于整站爬虫应该是个福音,URL 管理比较方便:

内容页面通常都是分页的,一次抓取不了太多,这个库可以获取分页信息:

结果如下:

通过迭代器实现了智能发现分页,这个迭代器里面会用一个叫 _next 的方法,贴一段源码感受下:

通过查找 a 标签里面是否含有指定的文本来判断是不是有下一页,通常我们的下一页都会通过 下一页 或者 加载更多 来引导,他就是利用这个标志来进行判断。默认的以列表形式存在全局: ['next','more','older'] 。我个人认为这种方式非常不灵活,几乎没有扩展性。 感兴趣的可以往 github 上提交代码优化。

也许是考虑到了现在 js 的一些异步加载,这个库支持 js 运行时,官方说明如下:

使用非常简单,直接调用以下方法:

第一次使用的时候会下载 Chromium,不过国内你懂的,自己想办法去下吧,就不要等它自己下载了。render 函数可以使用 js 脚本来 *** 作页面,滚动 *** 作单独做了参数。这对于上拉加载等新式页面是非常友好的。

首先,你一定用过魔术方法,也一定见过魔术方法。以下划线开头的方法,比如:

这些被统称为魔术方法。

给整数和字符串做加法:

我们写个表示城市的类,它有两个属性:城市名和人口。

然后我们给两个城市做加法,发现不能相加:

报错是说City不支持"+"号,如何让它支持"+"呢?需要给类加上魔术方法__add__就可以相加了。

我们给City添加一个__add__的方法,城市相加,人口相加,创建一个新的城市:

这说明__add__有一定的魔力,当我们用到加号"+"时,python就回去寻找这个方法,如果这个对象没有这个方法就会报错。

python中,所有的运算符都是通过魔术方法来实现的。

如果我们在City类有以下方法,就可以做加减乘除了:

我们再来打印int和str查看他们的方法,int有加减乘除,str只有__add__ __mul__,它只能做加法和乘法:

列表为什么能获取元素, __getitem__,可以再任何一个类里加上这个方法,然后也就可以用[]方括号来获取元素:

我们使用最多的方法一定是__new__和__init__, 在新建方法的时候,都会调用到这两个方法:

不止有魔术方法,还有魔术属性,形如"__yyy__",通常是python自动设置的属性,我们可以使用这些属性,比如:

什么使用str方法,什么时候用repr方法?

如果我们想让print打印出来好看,可以定义__str__的方法:

这里有各种策略用于定位网页中的元素(locate elements),你可以选择最适合的方案,Selenium提供了一下方法来定义一个页面中的元素:

find_element_by_id

find_element_by_name

find_element_by_xpath

find_element_by_link_text

find_element_by_partial_link_text

find_element_by_tag_name

find_element_by_class_name

find_element_by_css_selector

        下面是查找多个元素(这些方法将返回一个列表):

find_elements_by_name

find_elements_by_xpath

find_elements_by_link_text

find_elements_by_partial_link_text

find_elements_by_tag_name

find_elements_by_class_name

find_elements_by_css_selector

除了上面给出的公共方法,这里也有两个在页面对象定位器有用的私有方法。这两个私有方法是find_element和find_elements。

常用方法是通过xpath相对路径进行定位,同时CSS也是比较好的方法。举例:

[html] view plain copy

<html>

<body>

<form id="loginForm">

<input name="username" type="text" />

<input name="password" type="password" />

<input name="continue" type="submit" value="Login" />

<input name="continue" type="button" value="Clear" />

</form>

</body>

<html>

        定位username元素的方法如下:

[python] view plain copy

username = driverfind_element_by_xpath("//form[input/@name='username']")

username = driverfind_element_by_xpath("//form[@id='loginForm']/input[1]")

username = driverfind_element_by_xpath("//input[@name='username']")

        [1] 第一个form元素通过一个input子元素,name属性和值为username实现

        [2] 通过id=loginForm值的form元素找到第一个input子元素

        [3] 属性名为name且值为username的第一个input元素

二 *** 作元素方法

在讲述完定位对象(locate elements)之后我们需要对该已定位对象进行 *** 作,通常所有的 *** 作与页面交互都将通过WebElement接口,常见的 *** 作元素方法如下:

clear 清除元素的内容

send_keys 模拟按键输入

click 点击元素

submit 提交表单

举例自动访问FireFox浏览器自动登录163邮箱。

[python] view plain copy

from selenium import webdriver

from seleniumwebdrivercommonkeys import Keys

import time

# Login 163 email

driver = webdriverFirefox()

driverget("")

elem_user = driverfind_element_by_name("username")

elem_userclear

elem_usersend_keys("15201615157")

elem_pwd = driverfind_element_by_name("password")

elem_pwdclear

elem_pwdsend_keys("")

elem_pwdsend_keys(KeysRETURN)

#driverfind_element_by_id("loginBtn")click()

#driverfind_element_by_id("loginBtn")submit()

timesleep(5)

assert "baidu" in drivertitle

driverclose()

driverquit()

        首先通过name定位用户名和密码,再调用方法clear()清除输入框默认内容,如“请输入密码”等提示,通过send_keys("")输入正确的用户名和密码,最后通过click()点击登录按钮或send_keys(KeysRETURN)相当于回车登录,submit()提交表单。

        PS:如果需要输入中文,防止编码错误使用send_keys(u"中文用户名")。

三 WebElement接口获取值

通过WebElement接口可以获取常用的值,这些值同样非常重要。

size 获取元素的尺寸

text 获取元素的文本

get_attribute(name) 获取属性值

location 获取元素坐标,先找到要获取的元素,再调用该方法

page_source 返回页面源码

drivertitle 返回页面标题

current_url 获取当前页面的URL

is_displayed() 设置该元素是否可见

is_enabled() 判断元素是否被使用

is_selected() 判断元素是否被选中

tag_name 返回元素的tagName

数组允许进行批量 *** 作而无需使用for循环,因此更加简便,这种特性也被称为向量化。任何两个等尺寸之间的算术 *** 作都应用逐元素 *** 作的方式进行。

同尺度数组之间的比较,会产生一个布尔型数组。

上述 *** 作均是在同尺度数组之间进行的,对于不同尺度数组间的 *** 作,会使用到广播特性。

索引:获取数组中特定位置元素的过程;

切片:获取数组元素子集的过程。

new_a = aastype(new_type)

astype()方法一定会创建新的数组(原始数据的一个拷贝),即使两个类型一致。

ls = atolist()

转置是一种特殊的数据重组形式,可以返回底层数据的视图而不需要复制任何内容。

数组拥有 transpose 方法,也有特殊的 T 属性。

对于更高纬度的数组, transpose 方法可以接受包含轴编号的元组,用于转置轴。

ndarray的 swapaxes 方法,通过接受一对轴编号作为参数,并对轴进行调整用于重组数据。

swapaxes 方法返回的是数据的视图,而没有对数据进行复制。

Reference:

《Python for Data Analysis:Data Wrangling with Pandas,Numpy,and IPython》

以上就是关于python怎么定位富文框textarea的元素我用xpath定位包找不到元素全部的内容,包括:python怎么定位富文框textarea的元素我用xpath定位包找不到元素、python+selenium怎么遍历一个网页中class相同的值、python使用xpath(超详细)等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/10149968.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-05
下一篇 2023-05-05

发表评论

登录后才能评论

评论列表(0条)

保存