python - 使用 XPath 和 Scrapy/lxml 排除特定子节点

标签 python html xpath scrapy

我有一些使用 scrapy 抓取 bbcode 论坛的 Python 代码,我需要一个 Xpath 表达式,它只提供帖子的文本,不包括引号中的文本。 HTML 看起来像这样:

<td class="postbody">
   hi this is a response
   <div class="bbc-block">
      <blockquote>
         blah blah blah here's a quote
         <br>
      </blockquote>
   </div>
   <br>
   and now I'm responding to what I quoted
</td>
<td class="postbody">
   <div class="bbc-block">
      <blockquote>
         and now I'm responding to what I quoted
         <br>
      </blockquote>
   </div>
   <br>
   wow what a great response
</td>

对于每篇文章,每页都会出现多次这种情况。我最终想要的只是排除 block 引用的每个 td 节点的文本:

  1. 您好,这是回复\n,现在我正在回复我引用的内容
  2. 哇, react 真好

我必须提取这些 block 的 Python 代码如下——首先我将它从 scrapy 的 HtmlResponse 转换为 lxml 的 HtmlElement 类,因为这是我唯一能想到使用 lxml.html.text_content() 方法的方法:

import lxml.html as ht

def posts_from_response(self, response):
    dom = ht.fromstring(response.body)
    posts = dom.xpath('//td[@class="postbody"]')
    posts_text = [p.text_content() for p in posts]
    return posts_text

我已经广泛搜索了几天的解决方案,并尝试了大约十几种

'//td[@class="postbody"][not(@class="bbc-block")]'

以各种方式附加到它,但没有什么能让我得到我想要的分组。

是否有 1. 一种通过单个语句获得此信息的方法,或者 2. 一种在我的 posts 列表上执行第二个 Xpath 选择器以排除 bbc-block 节点的方法?

最佳答案

只获取 try 的直接子文本:

//*[@class='postbody']/text()  

要获取 td 中的所有文本元素,但忽略类为 bbc-block 的 div 中的文本:

 //td//text()[not(ancestor::*[@class='bbc-block'])]"

关于python - 使用 XPath 和 Scrapy/lxml 排除特定子节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36534197/

相关文章:

html - 在 header bootstrap 和 angular 中包含搜索

php - 字符被编码为 �

xml - XSLT : Parse with multiple same name

html - XPath//*[text()]没有选择我想要的文本

python - .set_function ---- 是这个方法还是什么?

python - 如何从单独的进程(例如,编辑器、vim)在 Jupyter Notebook 服务器中创建和执行单元格?

python - 使用类作为特殊值?

jquery - 如何让父div跟随45度旋转的子div的高度

python - 如何在 selenium for python 中转义 xpath 1.0 中的单引号

python - 计算 1/tanh(x) - 1/x 对于非常小的 x