为什么Selenium点不到元素

最近做了许多登陆项目,我会优先选择使用requests来模拟请求,但是有些参数实在是很难获取,这个时候我会使用Selenium,也还是遇到了各种坑,也算是见识到了很多的验证措施。

今天说说如何解决selenium点选不到数据的问题。

等待

这还是最常见的一种情况,推荐最多的是使用显示等待:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Firefox()
driver.get("http://somedomain/url_that_delay_loading")
try:
    element = WebDriverWait(driver,10).until(
        EC.presence_of_element_located((By.ID,"myDynamicElement"))
    )
finally:
    driver.quit()

这段代码会等待10秒,如果10秒内找到元素则立即返回,否则会抛出TimeoutException异常。

但是我比较懒,因为time.sleep()可以达到同样效果。

鼠标事件

官方把它叫做“行为链”。ActionChains可以完成简单的交互行为,例如鼠标移动,鼠标点击事件,键盘输入,以及内容菜单交互。

click(on_element=None) ——单击鼠标左键

click_and_hold(on_element=None) ——点击鼠标左键,不松开

context_click(on_element=None) ——点击鼠标右键

double_click(on_element=None) ——双击鼠标左键

drag_and_drop(source, target) ——拖拽到某个元素然后松开

drag_and_drop_by_offset(source, xoffset, yoffset) ——拖拽到某个坐标然后松开

key_down(value, element=None) ——按下某个键盘上的键

key_up(value, element=None) ——松开某个键

move_by_offset(xoffset, yoffset) ——鼠标从当前位置移动到某个坐标

move_to_element(to_element) ——鼠标移动到某个元素

move_to_element_with_offset(to_element, xoffset, yoffset) ——移动到距某个元素(左上角坐标)多少距离的位置

perform() ——执行链中的所有动作

release(on_element=None) ——在某个元素位置松开鼠标左键

send_keys(*keys_to_send) ——发送某个键到当前焦点的元素

send_keys_to_element(element, *keys_to_send) ——发送某个键到指定元素

深入了解可以参考 https://blog.csdn.net/huilan_same/article/details/52305176

move_to_element_with_offsetclick_and_hold会经常用到破解验证码中。

触摸操作 (TouchAction)

该事件仅仅针对移动端、触屏版

flick_element(on_element, xoffset, yoffset, speed) # 以元素为起点以一定速度向下滑动

scroll_from_element(on_element xoffset yoffset) #以元素为起点向下滑动

double_tap(on_element)                                     #双击   

flick_element(on_element, xoffset, yoffset, speed)         #从元素开始以指定的速度移动

long_press(on_element)                                            #长按不释放

move(xcoord, ycoord)                                                #移动到指定的位置

perform()                                                                    #执行链中的所有动作

release(xcoord, ycoord)                                             #在某个位置松开操作

scroll(xoffset, yoffset)                                                      #滚动到某个位置

scroll_from_element(on_element, xoffset, yoffset)         #从某元素开始滚动到某个位置

tap(on_element)                                                             #单击

tap_and_hold(xcoord, ycoord)                                        #某点按住

为什么要说到移动端,在做登陆时,移动端往往会更加简单,但是触屏版的点击和PC端时完全不同的,点击与按住时不同的。

在某个项目我换成TouchAction后,神奇的发现,注册不再需要处理验证码了,真是太棒了。

使用js

当你使用浏览器已经找到该元素,使用click()方法但是不起作用时,这个时候建议尝试js,例如在我的主页 https://www.zhihu.com/people/cuishite/activities,点击 “查看详细资料”

python js = 'document.getElementsByClassName("Button ProfileHeader-expandButton Button--plain")[0].click();' driver.execute_script(js)

你可以先在控制台调试

js通常可以解决绝大多是问题,如果还是解决不了,那你可能和我遇到了同样的问题,比如说,我在处理某移动端网站登陆,处理如下验证码时,我会使用到move_to_element_with_offset,该方法是“移动到距某个元素(左上角坐标)多少距离的位置”。

计算出坐标后,会调用该方法,如action.move_to_element_with_offset(element, width, height).click().perform(),然而实际上问题并没有这么简单,多次点击失效。具体的有时间再说。

实用方法

提取selenium的cookies

介绍把selenium的cookies船体给requests使用的方法:

cookies = driver.get_cookies()

s = requests.Session()
for cookie in cookies:
    s.cookies.set(cookie['name'], cookie['value'])

How do I load session and cookies from Selenium browser to requests library in Python?

元素截图方法

from selenium import webdriver
from PIL import Image

fox = webdriver.Firefox()
fox.get('https://stackoverflow.com/')

# now that we have the preliminary stuff out of the way time to get that image :D
element = fox.find_element_by_id('hlogo') # find part of the page you want image of
location = element.location
size = element.size
fox.save_screenshot('screenshot.png') # saves screenshot of entire page
fox.quit()

im = Image.open('screenshot.png') # uses PIL library to open image in memory

left = location['x']
top = location['y']
right = location['x'] + size['width']
bottom = location['y'] + size['height']


im = im.crop((left, top, right, bottom)) # defines crop points
im.save('screenshot.png') # saves new cropped image

 selenium cannot screenshot a web element

最后推荐一个神器 appium/python-client

至于验证码部分,现在主要还是靠第三方工具,并没有自己尝试机器学习等方法处理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Selenium 定位不到元素时,可以尝试以下几种方法来解决问题: 1. 确保元素存在:首先确认元素是否确实存在于页面上,并且在定位元素之前是否已经加载毕。可以通过手动操作页面或者查看页面源代码来确认元素是否存在。 2. 使用不同的定位方法:尝试使用不同的定位方法来定位元素,例如使用 `find_element_by_id`、`find_element_by_xpath`、`find_element_by_css_selector` 等方法。有时候使用不同的定位方法可以解决定位问题。 3. 使用等待机制:等待页面加载成或者元素出现在页面上是很常见的操作,可以使用 Selenium 中的等待机制来等待元素的出现。例如使用 `WebDriverWait` 类结合 `expected_conditions` 来等待元素的可见性、可击等条件。 ```python from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By # 等待元素可见 element = WebDriverWait(driver, 10).until( EC.visibility_of_element_located((By.ID, "element_id")) ) # 或者等待元素击 element = WebDriverWait(driver, 10).until( EC.element_to_be_clickable((By.ID, "element_id")) ) ``` 4. 检查浏览器驱动:确保使用的浏览器驱动是最新版本,并且与当前浏览器版本兼容。 5. 检查元素定位表达式:检查使用的元素定位表达式是否正确,可以通过浏览器的开发者工具来检查元素的属性和路径。 如果尝试了以上方法仍然无法定位到元素,可以提供更多关于页面结构和目标元素的信息,以便更准确地帮助解决问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值