简体   繁体   English

Selenium 找不到 class 名称的元素

[英]Selenium can't find element by class name

I want to send a message to this webpage with Python.我想用 Python 向这个网页发送一条消息。

It is to say to do the following but with Python:也就是说,使用 Python 执行以下操作:

水图像介绍

That's why I tried the following script with Selenium:这就是我使用 Selenium 尝试以下脚本的原因:

#!/usr/bin/env python3

from selenium import webdriver


api_location = 'http://iphoneapp.spareroom.co.uk'
api_search_endpoint = 'flatshares'
api_details_endpoint = 'flatshares'

location = 'http://www.spareroom.co.uk'
details_endpoint = 'flatshare/flatshare_detail.pl?flatshare_id='

def contact_room(room_id):
    url = '{location}/{endpoint}/{id}?format=json'.format(location=api_location, endpoint=api_details_endpoint, id=room_id)
    print(url)
    driver_path = 'C:\Program Files\chromedriver'
    driver = webdriver.Chrome(executable_path = driver_path )  # Optional argument, if not specified will search path.
    # Go to your page url
    driver.get(url)
    # Get button you are going to click by its id ( also you could use find_element_by_css_selector to get element by css selector)
    button_element = driver.find_element_by_class_name('button button--wide')
    button_element.click()

But it returns:但它返回:

contact_room(14110387)

(roo_env) (base) C:\Users\antoi\Documents\Programming\roomfinder>python test_message.py
http://iphoneapp.spareroom.co.uk/flatshares/14110387

DevTools listening on ws://127.0.0.1:51038/devtools/browser/401513e8-f221-47f1-ba6b-a7b7f598d839
Traceback (most recent call last):
  File "test_message.py", line 24, in <module>
    contact_room(14110387)
  File "test_message.py", line 21, in contact_room
    button_element = driver.find_element_by_class_name('button button--wide')
  File "C:\ProgramData\Anaconda3\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 564, in find_element_by_class_name
    return self.find_element(by=By.CLASS_NAME, value=name)
  File "C:\ProgramData\Anaconda3\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 978, in find_element
    'value': value})['value']
  File "C:\ProgramData\Anaconda3\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "C:\ProgramData\Anaconda3\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":".button button--wide"}
  (Session info: chrome=77.0.3865.120)

While the button to access the messaging page is of the button button--wide class.而访问消息页面的按钮是button button--wide class。 In fact, in the source code there is:其实在源码中有:

<a class="button button--wide" data-ga-event-category="Listing Details" data-ga-event-action="clicked" data-ga-event-label="contact-box-email" href="/flatshare/flatshare_detail.pl?flatshare_id=14110387&amp;mode=contact&amp;submode=byemail&amp;flatshare_type=offered&amp;search_id=896264077&amp;search_results=%2Fflatshare%2F%3Fsearch_id%3D896264077%26&amp;city_id=9&amp;featured=&amp;alert_id=&amp;alert_type=&amp;upgrade_required=0&amp;" title="Email advertiser" rel="nofollow"><span><i class="far fa-envelope"></i>&nbsp;&nbsp;Message</span></a>

Trying find_element_by_css_selector('.button.button--wide')尝试find_element_by_css_selector('.button.button--wide')

Unfortunately, it tells me that I can't interact with the element:不幸的是,它告诉我无法与元素交互:

(roo_env) (base) C:\Users\antoi\Documents\Programming\roomfinder>python test_message.py
http://iphoneapp.spareroom.co.uk/flatshares/14110387

DevTools listening on ws://127.0.0.1:52677/devtools/browser/4965ddbe-4b24-4ae7-a7f5-e44a8cbf2eef
Traceback (most recent call last):
  File "test_message.py", line 25, in <module>
    contact_room(14110387)
  File "test_message.py", line 23, in contact_room
    button_element.click()
  File "C:\ProgramData\Anaconda3\lib\site-packages\selenium\webdriver\remote\webelement.py", line 80, in click
    self._execute(Command.CLICK_ELEMENT)
  File "C:\ProgramData\Anaconda3\lib\site-packages\selenium\webdriver\remote\webelement.py", line 633, in _execute
    return self._parent.execute(command, params)
  File "C:\ProgramData\Anaconda3\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "C:\ProgramData\Anaconda3\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable
  (Session info: chrome=77.0.3865.120)

Correct CSS Selector is: .button.button--wide :正确的 CSS 选择器是: .button.button--wide

在此处输入图像描述

So, in your case, it will be:因此,在您的情况下,它将是:

...
button_element = driver.find_element_by_css_selector(".button.button--wide")
...

UPD: Also, you can try to use explicit wait for locating element: UPD:另外,您可以尝试使用显式等待定位元素:

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

...
button_element = ui.WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".button.button--wide")))
button_element.click()

And completely working code is:完全有效的代码是:

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


API_LOCATION = "http://iphoneapp.spareroom.co.uk"
API_DETAILS_ENDPOINT = "flatshares"
ID = "14110387"
URL = "{location}/{endpoint}/{id}".format(
    location=API_LOCATION, endpoint=API_DETAILS_ENDPOINT, id=ID)

DRIVER = webdriver.Chrome()
DRIVER.get(URL)
ui.WebDriverWait(DRIVER, 10).until(
    EC.element_to_be_clickable((By.CSS_SELECTOR, "a.button.button--wide"))).click()

I hope it helps you!我希望它对你有帮助!

The reason you were getting json in the browser because you have passed wrong parameter value in the function.您在浏览器中获得 json 的原因是您在 function 中传递了错误的参数值。 You have provided api_details_endpoint this variable instead of details_endpoint .您提供了api_details_endpoint这个变量而不是details_endpoint Second thing with that class_name there is 11 elements to get unique use parent element as well.第二件事是 class_name 有 11 个元素可以获得唯一的使用父元素。

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

api_location = 'http://iphoneapp.spareroom.co.uk'
api_search_endpoint = 'flatshares'
api_details_endpoint = 'flatshares'

location = 'http://www.spareroom.co.uk'
details_endpoint = 'flatshare/flatshare_detail.pl?flatshare_id='

def contact_room(room_id):
    url = '{location}/{endpoint}/{id}?format=json'.format(location=api_location, endpoint=details_endpoint, id=room_id)
    print(url)
    driver_path = 'C:\Program Files\chromedriver'
    driver = webdriver.Chrome(executable_path = driver_path )  # Optional argument, if not specified will search path.
    # Go to your page url
    driver.get(url)
    WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.CSS_SELECTOR,"li.emailadvertiser > .button.button--wide"))).click()
    # Get button you are going to click by its id ( also you could use find_element_by_css_selector to get element by css selector)
    # button_element = driver.find_element_by_class_name('button button--wide')
    # button_element.click()

contact_room(14110387)

The element might be not getting loaded so it might gives no such element error.该元素可能没有被加载,因此它可能no such element错误。 You can add你可以加

driver.implicitly_wait(15)

line before searching for element.搜索元素之前的行。 (In this case, before driver.find_element_by_class_name('button button--wide') line.) (在这种情况下,在driver.find_element_by_class_name('button button--wide')行之前。)

Don't worry it won't be wait 15 seconds.不用担心它不会等待 15 秒。 Whenever it the element is loaded, selenium will find it.每当加载元素时,selenium 都会找到它。

You can try this get the element by xpath (is more simple):您可以尝试通过 xpath 获取元素(更简单):

Take a look for this post: Is there a way to get the XPath in Google Chrome?看看这篇文章: 有没有办法在 Google Chrome 中获取 XPath?

button_element = driver.find_element_by_xpath('your_xpath')
button_element.click()

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

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