使用 Python 和 Selenium 将鼠标悬停在图形上
Posted
技术标签:
【中文标题】使用 Python 和 Selenium 将鼠标悬停在图形上【英文标题】:Scraping hover over figure using Python and Selenium 【发布时间】:2018-06-19 04:33:10 【问题描述】:我正在尝试使用 Python 和 Selenium 从 http://fuelinsights.gasbuddy.com/Charts 抓取数据。困难的部分是数据仅在折线图上的一个点悬停时才会出现。目前,我的问题是无法创建所有悬停在对象上的列表。到目前为止,我的代码如下:
from selenium import webdriver as web
from selenium.webdriver.common.action_chains import ActionChains
driver = web.Chrome('driver path')
driver.get('http://fuelinsights.gasbuddy.com/Charts')
test= driver.find_elements_by_xpath('//*[@class="highcharts-markers"]')
print(test)
`
这给了我测试=[]。以前,我在所有的抓取项目中都使用了beautifulsoup,但我重做了一些以前的项目,以确保我了解Selenium 的工作原理并且没有遇到问题。
如果有人能帮我解决这个问题,我可以创建一个项目列表,我可以使用 ActionChains 将鼠标悬停在上面并从中提取价格和日期。
谢谢!
****编辑**** 为了澄清,我查看了许多其他关于 SVG 和 g 元素以及 Highcharts 的帖子,但我仍然缺乏解决这个问题的方法。我尝试了许多 Xpath(和其他 find_elements_by 选项),但只能得出两个结果:(1)Xpath 是有效的,但不包含任何元素,或者(2)InvalidSelectorException 表明我无法找到具有 xpath 表达式的元素。我相信这归结为简单地错误地指定了我的 Xpath,但我不知道如何找到正确的 Xpath。
【问题讨论】:
highcharts-markers
类位于 <g>
标记内,而svg
标记内。 Selenium WebDriver [Java]: How to Click on elements within an SVG using XPath 的可能重复项
感谢 DebanjanB,这提供了一些有用的见解。这些是非常相似的问题,但我无法使用链接中提供的建议解决方案来解决我的问题(诚然,这可能是由于我自己从 Java 转换为 Python 的缺点)。
【参考方案1】:
您不能使用上面提到的 Xpath 来定位 svg 标签内的元素。
可用于创建悬停对象列表的 Xpath 是:
//*[name()='svg']//*[name()='g' and @class='highcharts-markers']/*[name()='path']
我编写了一个 java 程序 来获取所有工具提示元素的文本。您可以使用逻辑并编写相应的python代码:
1. 获取工具提示元素列表
List <WebElement> highChartElements= driver.findElements(By.xpath("//*[name()='svg']//*[name()='g' and @class='highcharts-markers']/*[name()='path']"));
2。遍历列表并使用动作类来移动和单击所有工具提示元素
3.获取工具提示元素的文本。
for(WebElement element:highChartElements)
Actions action = new Actions(driver);
action.moveToElement(element).click().perform();
Thread.sleep(3000);
List<WebElement> highChartToolTipTextElements= driver.findElements(By.xpath("//*[name()='svg']//*[name()='g' and @class='highcharts-tooltip']/*[name()='text']/*[name()='tspan']"));
for(WebElement toolTipElement:highChartToolTipTextElements)
System.out.println("The text for the elements is"+toolTipElement.getText());
【讨论】:
莫妮卡,感谢您的指点。我不得不稍微调整您提供的 Xpath 以使其运行,但我仍然从 driver.find_elements_by_xpath 命令返回一个空列表。我的 Xpath 现在是 '//*[name()="svg"]//*[name()="g"]//*[@class="highcharts-markers"]/*[name="path" ]'你对如何解决这个问题还有其他建议吗? 不要更改 xpath,使用我提供的那个。 xpath 应该可以工作,我已经在我的机器上执行了程序并且它工作了。为什么要调整 Xpath? 您在 python 中使用以下命令test= driver.find_elements_by_xpath("//*[name()='svg']//*[name()='g' and @class='highcharts-markers']/*[name()='path']")
时指定的 Xpath 返回 test=[]。我不确定为什么这会为您提供结果,但对我没有任何回报。非常感谢任何进一步的指导!【参考方案2】:
谢谢你! 2 年后,我面临一个等效项目,并使用您的示例来学习如何使用 python 和 Firefox 完成工作。 也许下面的代码对某些人有用。
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
from selenium.webdriver.common.action_chains import ActionChains
driver = webdriver.Firefox(executable_path=r'path\to\the\geckodriver.exe')
driver.get('http://fuelinsights.gasbuddy.com/Charts')
element = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME, "highcharts-markers")))
test = driver.find_elements_by_xpath("//*[name()='svg']//*[name()='g' and @class='highcharts-markers']/*[name()='path']")
res = []
for el in test:
hover = ActionChains(driver).move_to_element(el)
hover.perform()
date = driver.find_elements_by_css_selector(".highcharts-tooltip > text:nth-child(5) > tspan:nth-child(1)")
price = driver.find_elements_by_css_selector(".highcharts-tooltip > text:nth-child(5) > tspan:nth-child(4)")
res.append((date[0].text, price[0].text))
“res”包含:
('Saturday, May 30, 2020', '1.978 $/gal')
('Friday, May 29, 2020', '1.979 $/gal')
('Thursday, May 28, 2020', '1.977 $/gal')
('Wednesday, May 27, 2020', '1.972 $/gal')
('Tuesday, May 26, 2020', '1.965 $/gal')
.......
【讨论】:
我被困在同一个问题上,但在不同的网站上。这个解决方案对我没有帮助以上是关于使用 Python 和 Selenium 将鼠标悬停在图形上的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Selenium Python 将鼠标从元素向上移动 9 个像素
selenium+python自动化93-鼠标事件(ActionChains)源码详解