这是关于lxml和Selenium处理xpath表达式的不同方式的第一个问题。 (尽管有些相似,我相信 is different from this question)。
所以让我们从一个简单的问题开始。
这是字符串:
my_str = """
<div class="container">
<div class="24">
<div class="25">forget me</div>
<div class="26">a target </div>
</div>
<div class="27">very desired
<div class="28">whatever</div>
<div class="29">another target</div>
</div>
<div class="30">go home
<div class="31">Nothing here</div>
<div class="32">somewhat desired</div>
</div>
</div>
"""
这是xpath表达式:
simple_expression = "//*[contains(text(), 'target')]"
现在让我们看看lxml是如何处理的:
import lxml.html
root = lxml.html.fromstring(my_str)
e = root.xpath(simple_expression)
for entry in e:
print(entry.text)
这将产生所需的输出:
目标
另一个目标
到硒:
from selenium.webdriver import Chrome
driver = Chrome()
driver.get("data:text/html;charset=utf-8,{html_content}".format(html_content=my_str))
e2 = driver.find_element_by_xpath(simple_expression)
print(e2.text)
这一次的输出仅为
目标
那么-首先,为什么会这样呢?其次,如何使硒属具有相同的产量?
答案 0 :(得分:3)
这是因为您使用了find_element_by_xpath
,它将返回单个元素和找到的第一项。
您需要使用driver.find_elements_by_xpath
来获取所有元素。
driver.find_elements_by_xpath(simple_expression)
from selenium.webdriver import Chrome
my_str = """
<div class="container">
<div class="24">
<div class="25">forget me</div>
<div class="26">a target </div>
</div>
<div class="27">very desired
<div class="28">whatever</div>
<div class="29">another target</div>
</div>
<div class="30">go home
<div class="31">Nothing here</div>
<div class="32">somewhat desired</div>
</div>
</div>
"""
simple_expression = "//*[contains(text(), 'target')]"
driver = Chrome()
driver.get("data:text/html;charset=utf-8,{html_content}".format(html_content=my_str))
e2 = driver.find_elements_by_xpath(simple_expression)
for e in e2:
print(e.text)
a target
another target
答案 1 :(得分:1)
在lxml情况下,您将获得节点列表并对其进行遍历。
e = root.xpath(simple_expression)
for entry in e:
print(entry.text)
与硒中一样,您正在使用find_element
,它将返回第一个匹配的元素。这就是为什么只得到一个节点的原因。尝试将其更改为find_elements
,并以与在lxml中相同的方式进行迭代。
示例代码:
e2 = driver.find_elements_by_xpath(simple_expression)
for e in e2:
print(e.text)