【问题标题】:Iterating Over Elements and Sub Elements With lxml使用 lxml 迭代元素和子元素
【发布时间】:2013-01-28 21:46:53
【问题描述】:

这是给合法的lxml 大师的。我有一个网络抓取应用程序,我想在其中迭代网站上的多个 div.content(内容是类)标签。一旦进入 div.content 标签,我想看看是否有任何 <a> 标签是 <h3> 元素的子元素。这似乎相对简单,只需尝试使用 div.cont 标签中的XPath 创建一个列表,即

linkList = tree.xpath('div[contains(@class,"cont")]//h3//a')

问题是,然后我想创建一个tuple,其中包含来自 div.content 框的链接以及来自同一 div.content 框的段落元素的文本。我显然可以遍历整个文档并存储所有段落文本以及所有链接,但是我没有任何真正的方法可以将适当的段落与<a> 标签匹配。

lxml 的Element.iter() 函数几乎可以通过遍历所有div.cont 元素来实现这一点,忽略那些没有<a> 标记的元素,并配对paragraph/a 组合,但不幸的是似乎没有使用该方法迭代类名的选项,只有标签名。

编辑:这是我要解析的 HTML 的极其精简的版本:

<body>
<div class="cont">
    <h1>Random Text</h1>
    <p>The text I want to obtain</p>
    <h3><a href="somelink">The link I want to obtain</a></h3>
</div>
</body>

我想使用许多这样的 div.conts —— 其中大多数都有比这更多的元素,但这只是一个草图,让您了解我正在使用的内容。

【问题讨论】:

  • 你能发布一些示例 HTML 吗?
  • 好的,刚刚发布了一个粗略的例子

标签: python lxml


【解决方案1】:

您可以只使用不太具体的 XPath 表达式:

for matchingdiv in tree.xpath('div[contains(@class,"cont")]'):
    # skip those without a h3 > a setup.
    link = matchingdiv.xpath('.//h3//a')
    if not link:
        continue

    # grab the `p` text and of course the link.

您可以扩展它(雄心勃勃)并选择h3 > a 标签,然后转到div.cont 祖先(基于XPath query with descendant and descendant text() predicates):

for matchingdiv in tree.xpath('.//h3//a/ancestor::*[self::div[contains(@class,"cont")]]'):
    # no need to skip anymore, this is a div.cont with h3 and a contained
    link = matchingdiv.xpath('.//h3//a')

    # grab the `p` text and of course the link

但是因为你需要扫描链接,但实际上并没有给你买任何东西。

【讨论】:

  • 这看起来很可靠。如果

    不是 class.cont 的直接子级,它还能工作吗?例如,如果

    包含在
    之类的包装器中?

  • @user1427661:这就是.// 前缀的作用;搜索当前元素的后代(不仅仅是子元素)。
猜你喜欢
相关资源
最近更新 更多
热门标签