Selenium selenium 定位问题

lyyyyyyy · April 30, 2019 · Last by lyyyyyyy replied at May 08, 2019 · 3083 hits

#我想定位到check in 和check out然后输入时间,但是尝试了很快都定位不到,现在尝试定位后面的button然后模拟shift+tab再返回到前面的输入框,还是定位不到。。。。有没有大佬能看一下为啥定位不到呢?有没有什么解决方案呢?谢谢各位啦


'''
from selenium import webdriver
import time

from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.maximize_window()
driver.get("https://pencd1.peninsula.com/en/hong-kong/luxury-hotel-room-suite-types/deluxe-room")
driver.find_element(By.XPATH,"/html/body/div[6]/div/div/div/div/div/div/button")
driver.close()
'''

共收到 45 条回复 时间 点赞

我是第一次遇到xpath定位不到的情况,以前我都是能不用xpath就不用xpath的,这个项目是真的头疼啊= =

lyyyyyyy Xpath 与 Css 定位 中提及了此贴 30 Apr 14:35

是不是因为没有加上等待时间?

夜雨声烦 回复

应该不是,因为我现在加了10秒的等待时间,还是没定位到

是不是不在一个frame里?可以下载一个在浏览器上使用xpath搜寻控件的插件试试

孙高飞 回复

不是,因为我看过都是div没有frame和iframe
这是url
https://pencd1.peninsula.com/en/hong-kong/luxury-hotel-room-suite-types/deluxe-room

想看下的,貌似你给的url不能直接访问啊
//input[@placeholder='Check in']或者直接id\name 这样不能直接定位到input输入框吗?
或者button试下可否定位到
//button[contains(.,'Check Availability')]

你搜索下源代码,看有没有相同的元素,并且隐藏了的

lyyyyyyy #10 · April 30, 2019 作者
Leticia 回复

有一个是相同的,所以我用的find_elements然后取索引,但是也不行= =不知道为何,可以帮忙看下吗?
url:
https://www.peninsula.com/en/hong-kong/luxury-hotel-room-suite-types/deluxe-room

因为你最下面这坨时间框不是在页面打开的时候就已经渲染好的。这坨dom是到达一定触发条件后再即时渲染的。你可以在刚进入的时候尝试在chrome开发者工具的inspector尝试搜索button.button-secondary,看看能搜出几个。然后再把页面拖到最下面,再看看能搜索出几个。

你可以先试试看scroll to bottom,然后再定位。

不是有Id么?

id="endDate"
id="startDate"

/html/body/div[6]/div/div/div/div/div/div/div/div/div/div/div/div[1]/input[1] 怎么可能定位不到呢?

元素定位不到的原因可能有以下几种情况:
1、元素在iframe里面
2、定位的元素在页面上有多个,或者id、name等是可变的
3、等待时间太短,导致选择器还没有跳转到该页面
4、窗口切换问题
5、页面还没加载出来,就找该元素
6、窗口没有最大化
你看看呢

我试了一下,check in和check out是可以定位的到的。我猜想你可能是想直接找到输入框,然后sendkeys("04/30/2019"),所以失败了。
因为输入框在点击button前后是不一样的,你可能需要三步,1点击button,2找到check in的input元素,3输入你想要的值。

zzx 回复

😅 页面有滚动条,还要滚动一下,元素在当前窗口不可见。

1.id不是唯一的

2.唯一定位的xpath之一为://input[@aria-describedby='DateInput__screen-reader-message-startDate_bookingbar']

定位不到可能是因为没拉滚动轴。。。

lyyyyyyy #19 · April 30, 2019 作者

感谢大佬,提醒了我,我去问了开发,我们这个网站所有的页面都是异步加载的,所以没有加载出来。再次感谢

lyyyyyyy #20 · April 30, 2019 作者
zzx 回复

是的,用你这个我也可以定位到了,但是我滚动条直接拉到底部也不行,也定位不到,只有拉到这个输入框的地方才能定位到,这是什么道理?

试了下,直接访问url页面后定位时定位不到的,需要:
1-先把滚动条下拉到输入框位置
2-然后使用//input[@aria-describedby='DateInput__screen-reader-message-startDate_bookingbar']可以定位到了

lyyyyyyy #22 · April 30, 2019 作者
cheunghr 回复

我来尝试一下,谢谢大佬

lyyyyyyy #23 · April 30, 2019 作者
hchengmx 回复

可否看一下你是怎么写的?我又尝试了一下check in定位,但是失败了。

lyyyyyyy #24 · April 30, 2019 作者

感谢,就是页面没加载出来,我以为等待一会就ok了,但是没考虑到异步加载

lyyyyyyy #25 · April 30, 2019 作者

确实尝试过,不行

应该是滚动条的问题,代码里那个xpath感觉以后会很难维护。。

Author only

js 有window.scrollto方法
webdriver可以执行js,所以你可以写一个函数,每100ms向下拖10个像素(根据渲染速度可以适当调整),循环(记得超时时间配置),直到滚动到找到对象为止

Author only

这xpath写得很蛋痛

from selenium import webdriver
import time

driver = webdriver.Chrome()
driver.maximize_window()
driver.get("https://www.peninsula.com/en/hong-kong/luxury-hotel-room-suite-types/deluxe-room")
js = "window.scrollTo(0,1500)"
driver.execute_script(js)
time.sleep(2)
startdata_element = driver.find_element_by_xpath("//input[@aria-describedby='DateInput__screen-reader-message-startDate_bookingbar']")
startdata_element.click()
startdata_element.send_keys("01/05/2019")
time.sleep(2)
enddata_element = driver.find_element_by_xpath("//input[@aria-describedby='DateInput__screen-reader-message-endDate_bookingbar']")
enddata_element.click()
enddata_element.send_keys("02/05/2019")
time.sleep(2)
driver.find_element_by_xpath("/html/body/div[6]/div/div/div/div/div/div/button").click()
lyyyyyyy #32 · May 02, 2019 作者
Yumy 回复

谢谢,我现在也是这样写的。
我现在想把所有的房间都遍历一遍点进去,但是leader说不能用img的alt,尝试了层级定位,各种定位都定位不到,可否帮忙看一下呢?
https://www.peninsula.com/en/hong-kong/luxury-hotel-room-suite-types
很是头疼,放假啥都没干= =

lyyyyyyy 回复

你看下img标签的dom规则 然后用xpath

lyyyyyyy 回复

我看了下页面,你可以用span标签对"查看客房详情"进行定位。
xpath = //span[contains(text(),'查看客房详情')]

lyyyyyyy #35 · May 07, 2019 作者

要考虑语言,所以这个感觉不行= =

lyyyyyyy #36 · May 07, 2019 作者
槽神 回复

可否教一下怎么写,我试了好几遍都不行,
setInterval(function(){document.documentElement.scrollTop=2500},100)
是在搞不定

lyyyyyyy 回复

我不用python的,所以具体实现我做不了,只提供思路,你要确保js得到了执行:
http://www.w3school.com.cn/jsref/met_win_scrollto.asp


xpath相对定位://*[@id="startDate" and @aria-describedby="DateInput__screen-reader-message-startDate_bookingbar" ]

lyyyyyyy #39 · May 07, 2019 作者
黑山老妖 回复

是的,现在用的就是这个。想请问一下,有没有什么办法解决异步加载呢?我发现我的脚本如果不滑动到指定的地点就获取不到这些元素

lyyyyyyy 回复

我认为既然设计的就是要滑动到指定位置才加载出这个元素,那你的脚本就要符合场景,向下滑动啊。向下滑动然后一个显示等待再执行就行了。最好不要去想办法去解决异步加载吧

lyyyyyyy 回复

其实这个页面很多元素公用一个class,你可以定位到酒店的图片,然后点击就行了。不行的话,你在看看这个div下面的其他元素,其实都有共同点的
xpath = //div[@class='cardRoomDetails-gallery']

其实可以试试 滚动条到 Check in 的地方 在加上等待时间 再去找check in的元素


xpath写得惨不忍睹。

换css selector试试

lyyyyyyy #45 · May 08, 2019 作者
田双杰 回复

谢谢已经解决了

lyyyyyyy #46 · May 08, 2019 作者
Bensir 回复

谢谢,已经解决了

需要 Sign In 后方可回复, 如果你还没有账号请点击这里 Sign Up