【问题标题】:Selenium/python - Clicking all elements which are in a particular divSelenium/python - 单击特定 div 中的所有元素
【发布时间】:2017-08-22 04:32:10
【问题描述】:

我正在学习使用 selenium 进行抓取,并且正在尝试其中一个 SAP 页面。

链接是: https://help.sap.com/viewer/2e167338c1b24da9b2a94e68efd79c42/4.2.4/en-US/

我打算做的是在目录面板上显示此页面的所有叶子/最后一级 URL。不幸的是,这些链接不是 html 的,只有当我们点击左侧面板上的每个侧边按钮时,它才会展开,而且,每个按钮点击都可以有更多的嵌套按钮!我需要点击所有这些并获取基础数据。

我从识别 xpath 开始并尝试单击它们,但它给出了以下错误:

import time
driver = webdriver.Chrome("/Users/tarun/Downloads/chromedriver")

driver.get("https://help.sap.com/viewer/2e167338c1b24da9b2a94e68efd79c42/4.2.4/en-US/")
time.sleep(20) #tried this
htmlSource = driver.page_source

buttonsSidePanel = driver.find_elements_by_xpath('//*[@id="toc"]/treecontrol/div/div[*]/div[1]/div[1]')
#also tried - //*[@id="toc"]/treecontrol/div/div[*]/div[1]/div[1]/span[1]
for x in buttonsSidePanel:
    x.click()
    time.sleep(1)


driver.close()

错误:ElementNotVisibleException: Message: element not visible

在这方面我有几个问题(如果其中一些是天真的很抱歉) 1.)当我检查元素时,元素在 html 中可见!我无法弄清楚做错了什么?

  1. 另外,如果单击按钮显示更多按钮,我如何递归单击底层按钮,或者有什么方法可以一次单击所有按钮然后抓取数据?我查看了一些 stackoverflow 问题,但无法解决我的任务

3.)点击按钮后,现在我们如何抓取新生成的内容?

【问题讨论】:

  • 您在哪一行得到异常?
  • @PrakashPalnati - 在 x.click() 行中,正如答案之一所建议的那样,这可能是时间问题,因为 7 次中有一次,它有效,但我仍然没有确定也不确定在哪里添加 time.sleep()

标签: python selenium web-scraping web-crawler


【解决方案1】:

您可以尝试使用 selenium 的 execute_script 运行简单的 js 脚本。 试试这个。你也可以使用类名来识别。

jscode='''
var allButtons=document.getElementsByClassName('collapseicon');
for( b of allButtons){
   b.click();
 }
'''

driver.execute_script(jscode);

还要抓取包括子下拉菜单在内的所有页面内容/响应,在下面的调用中使用,请求模块来检查这一点,

import requests
url = "https://help.sap.com/http.svc/getpagecontent?deliverableInfo=1&deliverable_loio=2e167338c1b24da9b2a94e68efd79c42&language=en-US&state=PRODUCTION&toc=1&version=4.2.4"
r = requests.get(url)
print (r.json())

【讨论】:

  • 感谢您的回答!也试试这个,你能指导我第三个问题吗?
  • 抓取新内容是什么意思?子下拉菜单??他们将拥有自己的选择器。如果您正在抓取,我建议您在该网站上使用 urllib/requests,因为它们的 API 调用正在进行,并且响应正在显示所有内容。在这种情况下,您可以只保存响应。
  • 是的,我的意思是子下拉菜单,但我们怎么知道新的选择器是什么?就像在脚本中一样?您能否详细说明 urllib/requests 部分?响应是否会显示所有显示的内容,甚至是内部链接,是吗?我不认为 javascript 部分会被渲染!
  • help.sap.com/http.svc/… 在浏览器的网络选项卡中查看此调用并观察 JSON 响应。它拥有左侧下拉菜单中的所有内容。使用 requests 或 urllib 获取响应。我将在答案中为此添加代码
  • 通常没有自动的方法,尤其是当您抓取外部网站时(对于内部,您可能会从开发团队了解)。通常我们会在浏览器中检查网络选项卡中具有有意义名称的 XHR 请求并检查它们的响应。 (在我们的例子中,url 是 getpagecontent)
【解决方案2】:

这可能是因为请求的元素不立即可见并且连接继续进行。

尝试使用预期条件等待(EC 等待)。

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
button = WebDriverWait(driver, 30).until(EC.presence_of_element_located((By.XPATH, '//*[@id="toc"]/treecontrol/div/div[*]/div[1]/div[1]')))

这将等到元素可见,然后执行进一步的步骤。

【讨论】:

  • 你的意思是 htmlSource = driver.page_source button = WebDriverWait(driver, 30).until(EC.presence_of_element_located((By.XPATH, '//*[@id="toc"]/treecontrol /div/div[*]/div[1]/div[1]'))) button.click()
  • 这仍然给出同样的错误,你能复制结果吗?
猜你喜欢
  • 2016-11-14
  • 1970-01-01
  • 2014-02-27
  • 2016-02-19
  • 2022-01-02
  • 2017-12-02
  • 2020-05-24
  • 1970-01-01
  • 2021-07-21
相关资源
最近更新 更多