我想使用Python向this webpage发送消息。
可以使用Python进行以下操作:
这就是为什么我用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()
但是它返回:
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)
访问消息页面的按钮属于button button--wide
类。实际上,在源代码中有:
<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&mode=contact&submode=byemail&flatshare_type=offered&search_id=896264077&search_results=%2Fflatshare%2F%3Fsearch_id%3D896264077%26&city_id=9&featured=&alert_id=&alert_type=&upgrade_required=0&" title="Email advertiser" rel="nofollow"><span><i class="far fa-envelope"></i> Message</span></a>
find_element_by_css_selector('.button.button--wide')
不幸的是,它告诉我不能与元素交互:
(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)
答案 0 :(得分:1)
正确的CSS选择器为:.button.button--wide
:
因此,在您的情况下,它将是:
...
button_element = driver.find_element_by_css_selector(".button.button--wide")
...
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()
完全有效的代码是:
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()
希望对您有帮助!
答案 1 :(得分:0)
该元素可能未加载,因此可能会出现no such element
错误。您可以添加
driver.implicitly_wait(15)
行,然后搜索元素。 (在这种情况下,在driver.find_element_by_class_name('button button--wide')
行之前。)
别担心,它不会等待15秒。每当元素被加载时,硒都会找到它。
答案 2 :(得分:0)
您可以尝试通过xpath获取元素(更简单):
看看这篇文章:Is there a way to get the XPath in Google Chrome?
button_element = driver.find_element_by_xpath('your_xpath')
button_element.click()
答案 3 :(得分:0)
由于在函数中传递了错误的参数值,所以在浏览器中获取json的原因。
您提供了api_details_endpoint
而不是details_endpoint
这个变量。
第二个问题是,使用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)