【问题标题】:XPath for sub-element's text value in lxmllxml 中子元素文本值的 XPath
【发布时间】:2015-02-14 17:37:41
【问题描述】:

首先,这样的事情有可能吗?

我一直在尝试通过使用网页中存在的“子元素文本值”来生成 Xpath 表达式。尝试在 Python 中使用 lxml(etree、html、getpath)、ElementTree 模块来执行此操作。但我不知道如何为网页中存在的值生成 Xpath 表达式。我完全了解 python 中的 Scrapy 框架,但这是不同的。

下面是我不完整的代码..

import urllib2, re
from lxml import etree

def wgetUrl(target):
    try:
        req = urllib2.Request(target)
        req.add_header('User-Agent', 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.3 Gecko/2008092417 Firefox/3.0.3')
        response = urllib2.urlopen(req)
        outtxt = response.read()
        response.close()
    except:
        return ''
    return outtxt


newUrl = 'http://www.iupui.edu/~webtrain/tutorials/tables.html' # homepage

dt = wgetUrl(newUrl)
parser = etree.HTMLParser()
tree   = etree.fromstring(dt, parser)

根据lxml documentation,他们正在手动创建元素树,但是我如何使用我读取和解析的 html 数据(在我的示例变量treedata)来访问子元素。 或者更重要的是,如果可能的话,子元素的文本值。

假设在上面的示例网页中,我想搜索表“Supplies and Expenses”并通过该值动态生成Xpath表达式 - Supplies and Expenses

有没有办法这样做!!!最终目标,我想实现的是读取网页并为网页中存在的子元素文本值生成Xpath。

【问题讨论】:

  • 您想为具有特定文本的元素生成 xpath?或者你想要一个像/html/body/div[6]/table/tbody/tr[1]/td/div/b 给定元素的“通用” xpath(可能在其他页面中有一些不同的文本)
  • 我想为具有特定文本的元素生成 xpath。如果我理解正确,则无需担心其他页面。
  • 下面的答案正是您想要的,xpath 指向具有特定文本的元素。如果您想要像/html/... 这样的xpath,请首先找到元素(可能在下面的答案中使用xpath 或遍历树。第二次自己追溯回根。

标签: python html xpath lxml elementtree


【解决方案1】:

根据部分文本值查找所有元素:

"//*[contains(text(), 'some_value')]"

例如,如果你有这个:

<div id="somediv">
    <span>Something is here</span>
    <a href="#">Click here</a>
</div>

你可以像这样找到所有包含单词“here”的子元素:

"//div[@id='somediv']//*[contains(text(), 'here')]"

或者,例如,您可以查找所有包含单词“Something”的 sub-div span 元素:

"//div[@id='somediv']//span[contains(text(), 'Something')]"

至于在lxml中解析这个:

from lxml import etree
outtxt = response.read()
root = etree.fromstring(outtxt)
root.xpath("my_xpath_expression")

更新:

要获取元素的完整 XPath 表达式,请使用 ElementTree.getPath() 方法,如下所示:

tree = etree.ElementTree(root)
# this will print XPath of all
# elements in 'root'
for e in root.iter():
    print tree.getpath(e)

【讨论】:

  • 这是一个很好的答案,但我的问题是让我们在上面的示例中说,从 "here" 开始,我可以一直为它生成 Xpath 表达式,直到 html 的头部.类似于回溯元素并生成 Xpath 表达式。 here 的 xpath 之类的东西:/html/body/div[6]/table/tbody/tr[1]/td/div/b/text() 我希望我说清楚了。
  • 是的,我明白了。再次检查我的答案,我更新了。
  • 我关注了你的更新,但我收到了错误TypeError: Argument 'element' has incorrect type (expected lxml.etree._Element, got list)。我更新了我的代码,就像你的输入一样,直到roottree。然后我尝试使用subElem = root.xpath('//*[contains(text(), "V A R I E T Y")]')print tree.getpath(root.xpath('//*[contains(text(), "V A R I E T Y")]')) 在网页中完全不重复的文本选择一个子元素,我收到此错误。这个[contains(text().. 是否返回 LIST 对象而不是我想要重新迭代ElementTree 对象。
  • 坦率地说,+1 供您参考。它工作正常,我可以为网页中的所有元素生成 XPATH。 欣赏。对我来说,问题总是为 特定子元素 生成 XPATH(借助该元素的文本值)
  • 我不确定这是否回答了您的问题,或者还有什么未解决的问题?
猜你喜欢
  • 2012-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-10
相关资源
最近更新 更多