51Testing软件测试论坛

标题: python的selenium小脚本定位元素问题,求助 [打印本页]

作者: leisijun    时间: 2016-11-28 11:14
标题: python的selenium小脚本定位元素问题,求助
本帖最后由 leisijun 于 2016-11-28 15:00 编辑

各位大神,向大家请教个问题。
用python的selenium写一个百度账号登陆的脚本
脚本:
from selenium import webdriver
import time as t

browser = webdriver.Chrome()
browser.get('http://www.baidu.com')
t.sleep(3)

#定位百度首页的登陆按钮
load_css = 'html body div#wrapper div#head div.head_wrapper div#u1 a.lb'
load_id = 'tj_login'      #为什么这里用name找不到元素
load_xpath = 'ml/body/div[4]/div[1]/div/div[3]/a[7]'
browser.find_element_by_css_selector(load_css).click()

#等位百度首页登陆账号和密码对话框的输入按钮
name_css = 'html body div#passport-login-pop.tang-pass-pop-login-noimg.tang-pass-pop-login-merge.tang-pass-pop-login-tpl-mn.tang-pass-pop-login-color-blue.tang-pass-pop-login div#TANGRAM__PSP_2__foreground.tang-foreground div#TANGRAM__PSP_2__body.tang-body div#TANGRAM__PSP_2__content.tang-content div#passport-login-pop-dialog div.clearfix div.pass-login-pop-content div.pass-login-pop-form div#passport-login-pop-api.tang-pass-login form#TANGRAM__PSP_8__form.pass-form.pass-form-normal p#TANGRAM__PSP_8__userNameWrapper.pass-form-item.pass-form-item-userName input#TANGRAM__PSP_8__userName.pass-text-input.pass-text-input-userName'
name_id = 'TANGRAM__PSP_8__userName'
name_xpath = '//*[@id="TANGRAM__PSP_8__userName"]'
#这里用三种方式都找不到用户名输入框的元素?
browser.find_element_by_css_selector(css).click()
browser.find_element_by_css_selector(css).clear()


对象1.
百度首页右上角的登陆按键
使用css定位可行,使用name与xpath定位失败,代码见上
使用firebug审查元素结果为:
<a href="https://passport.baidu.com/v2/?login&amp;tpl=mn&amp;u=http%3A%2F%2Fwww.baidu.com%2F" name="tj_login" class="lb">登录</a>
错误的结果:
xpath的结果:
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: /html/body/div[4]/div[1]/div/div[3]/a[7]

对象2.
click百度右上角的登陆按键后出现的对话框
使用id,name,xpath,css定位全部失败。
使用firebug审查元素结果为:
<input id="TANGRAM__PSP_8__userName" name="userName" class="pass-text-input pass-text-input-userName open" autocomplete="off" placeholder="手机/邮箱/用户名" type="text">

失败报错:
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: html body div#passport-login-pop.tang-pass-pop-login-noimg.tang-pass-pop-login-merge.tang-pass-pop-login-tpl-mn.tang-pass-pop-login-color-blue.tang-pass-pop-login div#TANGRAM__PSP_2__foreground.tang-foreground div#TANGRAM__PSP_2__body.tang-body div#TANGRAM__PSP_2__content.tang-content div#passport-login-pop-dialog div.clearfix div.pass-login-pop-content div.pass-login-pop-form div#passport-login-pop-api.tang-pass-login form#TANGRAM__PSP_8__form.pass-form.pass-form-normal p#TANGRAM__PSP_8__userNameWrapper.pass-form-item.pass-form-item-userName input#TANGRAM__PSP_8__userName.pass-text-input.pass-text-input-userName

作者: Bugkiller    时间: 2016-11-28 13:27
前排
作者: 若尘_51    时间: 2016-11-28 14:02
你的脚本下面这两个地方有错:
browser.find_element_by_css_selector(css).click()
browser.find_element_by_css_selector(css).claer()

css-->name_css

claer()-->clear()

你的三种定位的地位都是可以
(不过我实在Firefox执行的,我的谷歌坏了,你换火狐试试,或许你这不是定位的问题)


作者: leisijun    时间: 2016-11-28 14:27
若尘_51 发表于 2016-11-28 14:02
你的脚本下面这两个地方有错:
browser.find_element_by_css_selector(css).click()
browser.find_elemen ...

谢谢您的回复与指出错误。
但是我用火狐浏览器依然报一样的错误。
selenium.common.exceptions.InvalidSelectorException: Message: Given css selector expression "//*[@id="TANGRAM__PSP_8__userName"]" is invalid: InvalidSelectorError: An invalid or illegal string was specified: "//*[@id="TANGRAM__PSP_8__userName"]"
作者: 若尘_51    时间: 2016-11-28 14:29
leisijun 发表于 2016-11-28 14:27
谢谢您的回复与指出错误。
但是我用火狐浏览器依然报一样的错误。
selenium.common.exceptions.Invalid ...

你怎么可以用xpath的值(//*[@id="TANGRAM__PSP_8__userName"]")用到css selector的定位方法里呢?
作者: leisijun    时间: 2016-11-28 14:44
若尘_51 发表于 2016-11-28 14:29
你怎么可以用xpath的值(//*[@id="TANGRAM__PSP_8__userName"]")用到css selector的定位方法里呢?

不好意思。错误复制错了。
xpath的结果:
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: /html/body/div[4]/div[1]/div/div[3]/a[7]
css的结果:
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: html body div#passport-login-pop.tang-pass-pop-login-noimg.tang-pass-pop-login-merge.tang-pass-pop-login-tpl-mn.tang-pass-pop-login-color-blue.tang-pass-pop-login div#TANGRAM__PSP_2__foreground.tang-foreground div#TANGRAM__PSP_2__body.tang-body div#TANGRAM__PSP_2__content.tang-content div#passport-login-pop-dialog div.clearfix div.pass-login-pop-content div.pass-login-pop-form div#passport-login-pop-api.tang-pass-login form#TANGRAM__PSP_8__form.pass-form.pass-form-normal p#TANGRAM__PSP_8__userNameWrapper.pass-form-item.pass-form-item-userName input#TANGRAM__PSP_8__userName.pass-text-input.pass-text-input-userName

作者: 清晨一缕阳光    时间: 2016-11-28 14:47
建议把你的完成代码贴出来,然后把相应的HTML代码也贴出来,查看,分析问题比较方便。
作者: leisijun    时间: 2016-11-28 15:00
清晨一缕阳光 发表于 2016-11-28 14:47
建议把你的完成代码贴出来,然后把相应的HTML代码也贴出来,查看,分析问题比较方便。

谢谢,已经把主题内容全部重新更新,麻烦帮忙看看,谢谢
作者: 若尘_51    时间: 2016-11-28 15:39
leisijun 发表于 2016-11-28 15:00
谢谢,已经把主题内容全部重新更新,麻烦帮忙看看,谢谢

这都是最基本的元素定位,估计都是你粗心写错了。
下面的脚本根据你的修改,你对比下看看,自己哪里错了:

# -*- coding: utf-8 -*-
from selenium import webdriver
import time

browser = webdriver.Firefox()
browser.get('http://www.baidu.com')
time.sleep(3)
browser.maximize_window()


#-----------登陆的三种定位方式-------
'''
#css定位:
login_css = 'html body div#wrapper div#head div.head_wrapper div#u1 a.lb'
browser.find_element_by_css_selector('html body div#wrapper div#head div.head_wrapper div#u1 a.lb').click()
'''

#xpath定位:
login_xpath = '/html/body/div[3]/div[1]/div/div[3]/a[7]'
browser.find_element_by_xpath(login_xpath).click()


'''
#name定位这个方法不可用,因为有多个name = 'tj_login')
login_name = 'tj_login'
browser.find_element_by_name(login_name).click()
'''

time.sleep(3)

#-----------用户名的三种定位方式-------
'''
#css定位:
name_css = 'html body div#passport-login-pop.tang-pass-pop-login-noimg.tang-pass-pop-login-merge.tang-pass-pop-login-tpl-mn.tang-pass-pop-login-color-blue.tang-pass-pop-login div#TANGRAM__PSP_2__foreground.tang-foreground div#TANGRAM__PSP_2__body.tang-body div#TANGRAM__PSP_2__content.tang-content div#passport-login-pop-dialog div.clearfix div.pass-login-pop-content div.pass-login-pop-form div#passport-login-pop-api.tang-pass-login form#TANGRAM__PSP_8__form.pass-form.pass-form-normal p#TANGRAM__PSP_8__userNameWrapper.pass-form-item.pass-form-item-userName input#TANGRAM__PSP_8__userName.pass-text-input.pass-text-input-userName'
browser.find_element_by_css_selector(name_css).click()
browser.find_element_by_css_selector(name_css).clear()
browser.find_element_by_css_selector(name_css).send_keys("username")
'''

'''
#id定位:
name_id = 'TANGRAM__PSP_8__userName'
browser.find_element_by_id(name_id).click()
browser.find_element_by_id(name_id).clear()
browser.find_element_by_id(name_id).send_keys("username")
'''


#xpath定位:
name_xpath = '//*[@id="TANGRAM__PSP_8__userName"]'
browser.find_element_by_xpath(name_xpath).click()
browser.find_element_by_xpath(name_xpath).clear()
browser.find_element_by_xpath(name_xpath).send_keys("username")

作者: leisijun    时间: 2016-11-28 16:15
若尘_51 发表于 2016-11-28 15:39
这都是最基本的元素定位,估计都是你粗心写错了。
下面的脚本根据你的修改,你对比下看看,自己哪里错了 ...

谢谢你,第一个按键的xpath确实是我粗心大意弄错了。刚开始学selenium,还有点生硬。

第二个元素的查找与第一个元素的查找2者之间,页面发生了变换,需要加一个延时,不然会报错。这一点我确实没有想到。找了网上相关的资料都没有看到sleep的动作。现在知道了。

非常感谢,问题完美解决
作者: qiguojie    时间: 2016-11-28 19:03
webdriver在操作web上的各个交互时,要按照实际考虑是否增加sleep,或者在框架上考虑增加自动重复查询多少秒,直到出现才操作;

跳转或者页面js渲染都会影响webdriver的识别(比如一些移动啊、拖拽啊、展开啊之类的),做的多了就有经验了
作者: leisijun    时间: 2016-11-29 09:56
qiguojie 发表于 2016-11-28 19:03
webdriver在操作web上的各个交互时,要按照实际考虑是否增加sleep,或者在框架上考虑增加自动重复查询多少 ...

谢谢您的宝贵经验之谈




欢迎光临 51Testing软件测试论坛 (http://bbs.51testing.com/) Powered by Discuz! X3.2