简体   繁体   English

无法通过Python(Selenium)在网络中找到find_element

[英]Unable to find_element in web through Python (selenium)

First of all, sorry for my English. 首先,对不起我的英语。 I'm from Buenos Aires, and I've started learning Python just a few weeks ago. 我来自布宜诺斯艾利斯,几周前我才开始学习Python。 Furthermore, I have a really basic knowledge in programming. 此外,我在编程方面具有非常基础的知识。 All I was able to do so far was by getting the info from internet (no formal education in this matter-I was studying Accounting last year). 到目前为止,我所能做的就是从互联网上获取信息(这方面没有正规的教育,我去年正在学习会计)。

As of this post, I want to find an element in a web page but I can't seem to get it right. 截至本文发布时,我想在网页中找到一个元素,但似乎无法正确处理。 I've even tried to click on "space" key-the simplest thing to do in this case. 我什至尝试单击“空格”键-在这种情况下最简单的操作。

I want to click on "OK" button. 我想单击“确定”按钮。

I have from "Inspect element": 我来自“检查元素”:

<div class="alert" id="popup_content">
  <div id="popup_message">No Pending Documents</div>
  <div id="popup_panel">
    <input id="popup_ok" type="button" value="OK">
  </div>
</div>

print: I've tried these 5 codes: 打印:我已经尝试了以下5个代码:

from selenium.webdriver.common.action_chains import ActionChains
element_ok = driver.find_element_by_xpath("//input[@id='popup_ok']")
Action.Chains(driver).move_to_element(element_ok).perform()
element.click()
driver.find_element_by_xpath(".//*[@id='popup_ok']/div/input").click()
driver.find_element_by_css_selector(".button_main[value='OK']").click()
clear_button = driver.find_element_by_xpath("//input[@id='popup_panel'][@type='button']")
clear_button = driver.find_element_by_xpath("//form[@id='popup_ok']/input[1]")
import keyboard
keyboard.press_and_release('shift+s, space')

Would someone help me get through this? 有人可以帮我解决这个问题吗?

PS: I'm using selenium (read from it in the book 'Automate the Boring Stuff with Python. Practical Programming for Total Beginners'. And chrome webdriver. PS:我正在使用硒(在《用Python自动化乏味的东西。面向初学者的实用编程》一书中阅读)以及chrome webdriver。

Let's take a look at each approach. 让我们看一下每种方法。


1. 1。

from selenium.webdriver.common.action_chains import ActionChains
element_ok = driver.find_element_by_xpath("//input[@id='popup_ok']")
Action.Chains(driver).move_to_element(element_ok).perform()
element.click()

This has two problems. 这有两个问题。

First, you import ActionChains , but then try to use it as Action.Chains . 首先,导入ActionChains ,然后尝试将其用作Action.Chains Because you didn't import anything called Action , you'll likely see this error: 因为您没有导入任何称为Action ,所以您可能会看到此错误:

NameError: name 'Action' is not defined

Removing the extra inner . 删除多余的内部. should fix it: 应该解决它:

ActionChains(driver).move_to_element(element_ok).perform()

Second, you find the element and save it to a variable named element_ok . 其次,找到元素并将其保存到名为element_ok的变量中。 Then, however, you try to call click() on a variable named element . 但是,然后,您尝试在名为element的变量上调用click() Because you haven't defined a variable with that name, you'll likely see this error: 由于您尚未使用该名称定义变量,因此您可能会看到此错误:

NameError: name 'element' is not defined

Calling element_ok.click() should fix it: 调用element_ok.click()应该可以解决此问题:

element_ok.click()

Note: You probably don't need to use ActionChains at all. 注意:您可能根本不需要使用ActionChains You should only need to tell Selenium to move to the element if the element is outside of the viewport, eg, "below the fold": 如果该元素位于视口之外,则只需告诉Selenium移至该元素即可,例如,“在折叠下方”:

element_ok = driver.find_element_by_xpath("//input[@id='popup_ok']")
element_ok.click()

2. 2。

driver.find_element_by_xpath(".//*[@id='popup_ok']/div/input").click()

This XPath query tells Selenium to: 此XPath查询告诉Selenium:

  1. find an element with an id of "popup_ok" (A), 找到一个id"popup_ok"的元素(A),
  2. find a child of A that is a <div> (B), 找到A的子<div> (B),
  3. find a child of B that is an <input> (C), then 找到B的子元素,它是<input> (C),然后
  4. return C. 返回C。

This does not make sense for your HTML. 这对于您的HTML没有意义。 The element with id "popup_ok" is an <input> , which has neither a child <div> nor a grandchild <input> . id "popup_ok"的元素是<input> ,它既没有子元素<div>也没有孙子元素<input>

Since the element with id "popup_ok" (A) is the <input> you want , you can simply remove the remainder of the XPath query: 由于id "popup_ok" (A)的元素是您想要的<input> ,因此您只需删除XPath查询的其余部分即可:

driver.find_element_by_xpath(".//*[@id='popup_ok']").click()

3. 3。

driver.find_element_by_css_selector(".button_main[value='OK']").click()

This CSS selector tells Selenium to find and return the element that: 此CSS选择器告诉Selenium查找并返回以下元素:

  1. has the class button_main and 具有class button_main
  2. has a value of "OK" (A). value "OK" (A)。

Your button meets requirement 2, but not 1. It has no class button_main . 您的按钮满足要求2,但不满足1。它没有class button_main (There is no element with class button_main .) (class button_main没有元素。)

Instead, you can use * to match any element regardless of class name: 相反,您可以使用*来匹配任何元素,而与类名无关:

driver.find_element_by_css_selector("*[value='OK']").click()

However, this is not a great CSS selector. 但是,这不是一个很棒的CSS选择器。 Because * matches any element, it has the potential to be slow. 由于*匹配任何元素,因此可能会变慢。

Instead, you can match by the tag: 相反,您可以按标记进行匹配:

driver.find_element_by_css_selector("input[value='OK']").click()

4. 4。

clear_button = driver.find_element_by_xpath("//input[@id='popup_panel'][@type='button']")
clear_button = driver.find_element_by_xpath("//form[@id='popup_ok']/input[1]")

The first XPath query tells Selenium to: 第一个XPath查询告诉Selenium:

  1. find an <input> element that a. 找到一个<input>元素 has id "popup_panel" and b. id "popup_panel"和b。 has type "button" . 具有type "button"

Your button meets requirements 1 and 1b, but not 1a. 您的按钮符合要求1和1b,但不符合1a。 The id "popup_panel" is used by the grandparent <div> . 祖父母<div>使用id "popup_panel"

To fix it, you could just remove that requirement: 要解决此问题,您可以删除该要求:

clear_button = driver.find_element_by_xpath("//input[@type='button']")

The second XPath query tells Selenium to: 第二个XPath查询告诉Selenium:

  1. find a <form> element (A) that a. 找到一个<form>元素(A)。 has id "popup_ok" , then 具有id "popup_ok" ,然后
  2. find the first child of A that is an <input> (B). 查找A的第一个子元素,该子元素是<input> (B)。

Your button meets requirement 2, but not 1. Its parent is neither a <form> tag nor has an id of "popup_ok" . 您的按钮符合要求2,但不符合1。其父级既不是<form>标记,也不具有id "popup_ok"

Instead, the <input> has that id : 相反, <input>具有该id

clear_button = driver.find_element_by_xpath("//input[@id='popup_ok'][1]")

Note: [1] selects the first matching element. 注意: [1]选择第一个匹配元素。 Since id attributes should be unique, this is redundant and can be removed: 由于id属性应该是唯一的,因此这是多余的,可以删除:

clear_button = driver.find_element_by_xpath("//input[@id='popup_ok']")

5. 5。

import keyboard
keyboard.press_and_release('shift+s, space')

This might not work for a lot of reasons, which are probably not worth getting into. 由于许多原因,这可能不起作用,这可能不值得探讨。 Selenium has the ability to simulate keyboard events, so you probably don't need to use another Python package. Selenium具有模拟键盘事件的功能,因此您可能不需要使用其他Python软件包。

If you have the element that should receive the keyboard events, you can call send_keys() on it: 如果您具有应该接收键盘事件的元素,则可以在其上调用send_keys()

from selenium.webdriver.common.keys import Keys

element.send_keys(Keys.SPACE)

If you don't have the element, you can use ActionChains to send keyboard events to the currently active element: 如果没有该元素,则可以使用ActionChains将键盘事件发送到当前活动的元素:

ActionChains(driver).send_keys(Keys.SPACE).perform()

如果您知道元素的ID,请尝试:

driver.find_element_by_id('popup_ok').click()

There are multiple ways to locate element 定位元素有多种方法

1. Use by id 1.按编号使用

ok_btn = driver.find_element_by_id("popup_ok")

2. Use by xpath 2.通过xpath使用

ok_btn = driver.find_element_by_xpath("//input[@value='OK']")

OR 要么

ok_btn = driver.find_element_by_xpath("//input[@id='popup_ok']")

按照您共享的HTML ,单击带有OK文本的按钮,您必须诱使WebDriverWait使元素可单击,并且可以使用以下代码行:

WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[@class='alert' and @id='popup_content']//div[@class='popup_panel']/input[@id='popup_ok' and @value='OK']"))).click()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM