Selenium selenium 定位问题

lyyyyyyy · 2019年04月30日 · 最后由 lyyyyyyy 回复于 2019年05月08日 · 469 次阅读

# 我想定位到 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 定位 中提及了此贴 04月30日 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')]

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

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']

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

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

zzx 回复

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

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

cheunghr 回复

我来尝试一下,谢谢大佬

程航 回复

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

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

确实尝试过,不行

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

仅楼主可见

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

仅楼主可见

这 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()
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(),'查看客房详情')]

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

槽神 回复

可否教一下怎么写,我试了好几遍都不行,
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 回复

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

lyyyyyyy 回复

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

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


xpath 写得惨不忍睹。

换 css selector 试试

田双杰 回复

谢谢已经解决了

Bensir 回复

谢谢,已经解决了

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册