【问题标题】:Seleneium exceptions - arguments[0].click is not a function using execute_script() in Selenium PythonSelenium 异常 - arguments[0].click 不是在 Selenium Python 中使用 execute_script() 的函数
【发布时间】:2020-09-09 11:22:59
【问题描述】:

我正在使用 Python 和 Selenium 在此网站 (https://collegecrisis.shinyapps.io/dashboard/) 上抓取交互式地图。具体来说,我想从地图中获取在弹出窗口中找到的文本。

在第一次尝试使用 Scrapy 执行此操作后,我改变了策略,因为我正在寻找的信息在弹出窗口中,并且地图的可点击部分重叠,并且在遍历所有相关元素时无法全部访问。

我得到了异常:ElementClickInterceptedException 元素点击被拦截:元素在点 (391, 500) 处不可点击。其他元素会收到点击: (会话信息:chrome=Xxxx)

因此,我找到了一些建议尝试通过这种方法使用 javascript 与地图进行交互:

driver.execute_script('arguments[0].click();', element)

但是,我收到了错误(在其他类似问题中,受访者强调该错误表明括号和/或冒号丢失,它们不在代码中,错误只是显示下面没有它们的代码) : JavascriptException: javascript 错误: arguments[0].click 不是函数 (会话信息:chrome=85.0.4183.83)

我尝试使用 driver.execute_script('arguments[0].click();', element) 方法来查看这在地图中是否有效。单击“缩放”按钮时会发生这种情况:

zoom_btn = driver.find_element_by_class_name("leaflet-control-zoom-in")
driver.execute_script("arguments[0].click();", zoom_btn)

我可以在不使用 javascript 的情况下使用 .click() 点击地图上的各个点:

specific_node = driver.find_element_by_xpath('.//*[contains(@d, "M421.5685916444444,133.94770476315125a1,1 0 1,0 2,0 a1,1 0 1,0 -2,0 ")]')
specific_node.click()

但由于地图上的点重叠,我无法循环点击问题顶部提到的每个元素(然后抓取弹出窗口中的文本)。

到目前为止我使用的代码如下。最后一个 for 循环未完成,因为我无法让点击部分工作。

# import packages
from selenium import webdriver
from selenium.common.exceptions import ElementClickInterceptedException

# setup drivers
PATH = "/Applications/chromedriver"
driver = webdriver.Chrome(PATH)
driver.implicitly_wait(10) # seconds
driver.get("https://collegecrisis.shinyapps.io/dashboard/")

# find all class elements =leaflet-interactive
nodes = driver.find_elements_by_class_name("leaflet-interactive")

# loop through clickable elements and get text from pop-up
for node in nodes:
        node.click()
        # get text from popups (code to be finished). node.find_elements_by_xpath('.//div[@class = "leaflet-popup-content"]')

使用 ActionChains 的可行解决方案:

# import packages
from selenium import webdriver
from selenium.common.exceptions import ElementClickInterceptedException
from selenium.webdriver.common.action_chains import ActionChains
from time import sleep

# setup drivers
PATH = "/Applications/chromedriver"
driver = webdriver.Chrome(PATH)
driver.implicitly_wait(10) # seconds
driver.get("https://collegecrisis.shinyapps.io/dashboard/")

# find all class elements =leaflet-interactive
nodes = driver.find_elements_by_class_name("leaflet-interactive")

# use actionchains
nodelist = []

# loop through each node
for node in nodes:
    ActionChains(driver).move_to_element(node).click().perform() # Used actionchains class to click to open popup
    sleep(.5)
    nodelist.append(driver.find_element_by_class_name('leaflet-popup-content').text)
    ActionChains(driver).move_to_element(node).click().perform() #click to close popup

如果有人能进一步说明为什么 ActionChain 方法可以工作而不会遇到重叠的点,那就太好了。

同样,为什么 driver.execute_script('arguments[0].click();', element) 方法不起作用?

【问题讨论】:

  • 尝试将 find_element 移动到 for 循环中。

标签: javascript python selenium leaflet


【解决方案1】:

由于所有点都相互重叠,因此最好使用 ActionChains 类方法来模拟将鼠标光标移动到它们上方然后单击:

ActionChains(driver).move_to_element(node).click().perform() # Used actionchains class to click to open popup
time.sleep(.5)
contents.append(driver.find_element_by_class_name('leaflet-popup-content').text)
ActionChains(driver).move_to_element(node).click().perform() #click to close popup

【讨论】:

  • 这很奏效。仅供参考 - 必须导入 ActionChains、time.sleep 并在 for 循环中使用上面的代码。将完整的工作代码添加到我的帖子中
猜你喜欢
  • 2019-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-08
相关资源
最近更新 更多