我正在尝试使用 selenium
单击此网站上的“CSV”按钮
https://covid19-vaccine-report.ecdc.europa.eu/#6_Reported_data。
但是,使用下面的代码我收到错误
selenium.common.exceptions.ElementClickInterceptedException: Message: Element <button class="dt-button buttons-csv buttons-html5" type="button"> is not clickable at point (464,600) because another element <div class="cckBannerInner"> obscures it
。
代码:
import os
import glob
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium import webdriver
from webdriver_manager.firefox import GeckoDriverManager
from selenium.webdriver.firefox.options import Options
# get directory of the current script
CURR_DIR = os.path.dirname(os.path.abspath(__file__))
URL = 'https://covid19-vaccine-report.ecdc.europa.eu/#6_Reported_data'
ACCEPT_COOKIES_ID = 'cckAcceptCookies'
VACCINES_XPATH = '//*[@id="DataTables_Table_0_wrapper"]/div[5]/button[2]'
# before downloading new files, remove old ones
for f in glob.glob(os.path.join(CURR_DIR, "dataset_2021-W*")):
os.remove(f)
# this will prevent opening browser window
# (https://stackoverflow.com/a/60627463/1979665)
options = Options()
#options.add_argument("--headless")
# (https://stackoverflow.com/a/18440478/1979665)
# To prevent download dialog
profile = webdriver.FirefoxProfile()
profile.set_preference('browser.download.folderList', 2) # custom location
profile.set_preference('browser.download.manager.showWhenStarting', False)
profile.set_preference('browser.download.dir', CURR_DIR)
profile.set_preference('browser.helperApps.neverAsk.saveToDisk', 'text/csv')
# (https://stackoverflow.com/a/32416545/1979665)
profile.set_preference("network.cookie.cookieBehavior", 2)
# (https://stackoverflow.com/a/58727916/1979665)
browser = webdriver.Firefox(profile,
executable_path=GeckoDriverManager().install(),
options=options)
browser.get(URL)
wait = WebDriverWait(browser, 2000000)
# accept cookies
accept_cookies = browser.find_element_by_id(ACCEPT_COOKIES_ID)
browser.execute_script("arguments[0].click();", accept_cookies)
# download vaccines as CSV
wait.until(EC.element_to_be_clickable((By.XPATH, VACCINES_XPATH))).click()
browser.quit()
按钮的 XPATH 是通过 Firefox Web 开发者控制台的复制 XPath 功能获取的。
我已经阅读了许多其他建议的答案并尝试了他们的解决方案,但没有任何效果。
我使用 JavaScript 接受 cookie (
browser.execute_script("arguments[0].click();", accept_cookies)
),以便横幅消失,因为当我尝试使用其他方法时,我收到了错误 could not be scrolled into view
。
然后我使用
WebDriverWait
等待所需的按钮可单击(使用 element_to_be_clickable
)。
当代码运行时,我会看到浏览器窗口中发生了什么,并且我确实看到 cookie 被接受并且横幅消失了。然后页面向下滚动到 CSV 按钮,但我收到上述错误,就像该按钮仍然被 cookie 横幅隐藏一样。
确切的错误(我在这里重复一遍),确实是这样引用cookie横幅的:
selenium.common.exceptions.ElementClickInterceptedException: Message: Element <button class="dt-button buttons-csv buttons-html5" type="button"> is not clickable at point (464,600) because another element <p class="cckInform"> obscures it
我也尝试将等待时间增加到
5000000
,但没有任何区别。
工作代码
感谢@Prophet我能够让它发挥作用。诀窍是向下滚动页面,直到按钮变得可见,然后单击它。
我还以这种方式删除了“accept coockie”部分,这很好,因为现在我只需以这种方式处理一个元素。
更新后的工作代码:
import os
import glob
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium import webdriver
from webdriver_manager.firefox import GeckoDriverManager
from selenium.webdriver.firefox.options import Options
# get directory of the current script
CURR_DIR = os.path.dirname(os.path.abspath(__file__))
URL = 'https://covid19-vaccine-report.ecdc.europa.eu/#6_Reported_data'
VACCINES_XPATH = '//*[@id="DataTables_Table_0_wrapper"]/div[5]/button[2]'
# before downloading new files, remove old ones
for f in glob.glob(os.path.join(CURR_DIR, "dataset_2021-W*")):
os.remove(f)
# this will prevent opening browser window
# (https://stackoverflow.com/a/60627463/1979665)
options = Options()
#options.add_argument("--headless")
# (https://stackoverflow.com/a/18440478/1979665)
# To prevent download dialog
profile = webdriver.FirefoxProfile()
profile.set_preference('browser.download.folderList', 2) # custom location
profile.set_preference('browser.download.manager.showWhenStarting', False)
profile.set_preference('browser.download.dir', CURR_DIR)
profile.set_preference('browser.helperApps.neverAsk.saveToDisk', 'text/csv')
# (https://stackoverflow.com/a/32416545/1979665)
profile.set_preference("network.cookie.cookieBehavior", 2)
# (https://stackoverflow.com/a/58727916/1979665)
driver = webdriver.Firefox(profile,
executable_path=GeckoDriverManager().install(),
options=options)
driver.get(URL)
wait = WebDriverWait(driver, 2000000)
vaccines = wait.until(EC.element_to_be_clickable((By.XPATH, VACCINES_XPATH)))
driver.execute_script("arguments[0].scrollIntoView();", vaccines)
vaccines.click()
driver.quit()
请尝试以下操作:滚动查看所需按钮下方的其他一些元素,以便所需按钮不会被 cookies 横幅覆盖,然后尝试单击该按钮。
national_references = WebDriverWait(browser, 20).until(EC.presence_of_element_located((By.CSS_SELECTOR, "#national-references")))
actions = ActionChains(driver)
actions.move_to_element(national_references).perform()
wait.until(EC.element_to_be_clickable((By.XPATH, VACCINES_XPATH))).click()
UPD: 由于滚动到
national_references
是不可能的,因为它 is out of bounds of viewport width (1366) and height (630)
根据尝试时抛出的异常,因此使用 actions.move_to_element(national_references).perform()
将其滚动到视图中,我们可以向下滚动页面,直到 national_references
变得可见。