如何在XPath中包含格式化文本?

2024-10-03 11:22:27 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在为我的IT工作做一个项目,它要求我使用Scrapy/XPath编写一个scraper,从一个相当简单的HTML页面获取一组相当简单的数据。我已经把所有的东西都按我想要的方式运行,除了一些斜体文字(被抓取的网站是为了语言教育项目,在这个特定的文本字段中有很多斜体的例子)没有出现。在

下面是我在斜体问题出现之前成功使用的代码:

rawTitles = []
for sel in response.xpath('//h2[@class="video"]'):
    rawTitle = sel.xpath('text()').extract()
    rawTitles.append(rawTitle[0])
print rawTitles

我得到以下“打印rawTitles”的回报:

^{pr2}$

我想要的是这样的东西:

[u'\n<i>Mjadra</i>', u'\nVariations in Making <i>Mansaf</i>', u'\nMaking <i>Maqloobeh</i>', u'\nCommon Rice and Meat Dishes', u'\nRumens and <i>Mahashi</i>']

如果文本HTML标记不能包含在输出中,我至少希望包含纯文本。单词应该出现的空白似乎不是我能做的最好的。在

有人知道我想试试什么吗?如果我没有提供足够的信息,请告诉我。提前谢谢。在

编辑:下面是一个表条目的示例,我需要从中提取信息:

<td width="25%" valign="top" align="center">
<h2 class="video"><img src="content/pl_makingfood_mjadrah.jpg"     alt="Thumbnail image from video" width="160" height="120" /><br /><br />
<i>Mjadra</i></h2>      <p class="video">Video <br />

<a href="content/pl_makingfood_mjadrah.rm" class="main">real</a>&nbsp;&nbsp;
<a href="content/pl_makingfood_mjadrah.mp4" class="main" target="_blank">mp4</a><br /><br />

Palestinian Arabic &amp; English <br />
<a href="content/pl_makingfood_mjadrah.doc" target="_blank" class="main">  doc </a>&nbsp; &nbsp; 
<a href="content/pl_makingfood_mjadrah.pdf" target="_blank" class="main">  pdf </a></p>
</td>

Tags: 文本brtargetmainvideoh2contentclass
2条回答

让我们看看scrapy shell中的不同提取模式,从示例HTML构建一个选择器:

>>> import scrapy
>>> t = '''<td width="25%" valign="top" align="center">
... <h2 class="video"><img src="content/pl_makingfood_mjadrah.jpg"     alt="Thumbnail image from video" width="160" height="120" /><br /><br />
... <i>Mjadra</i></h2>      <p class="video">Video <br />
... 
... <a href="content/pl_makingfood_mjadrah.rm" class="main">real</a>&nbsp;&nbsp;
... <a href="content/pl_makingfood_mjadrah.mp4" class="main" target="_blank">mp4</a><br /><br />
... 
... Palestinian Arabic &amp; English <br />
... <a href="content/pl_makingfood_mjadrah.doc" target="_blank" class="main">  doc </a>&nbsp; &nbsp; 
... <a href="content/pl_makingfood_mjadrah.pdf" target="_blank" class="main">  pdf </a></p>
... </td>'''
>>> selector = scrapy.Selector(text=t, type="html")

首先,让我们循环<h2 class="video">元素(使用CSS选择器),并提取循环中每个标题的字符串表示:

^{pr2}$

我们丢失了<i>信息。在

让我们尝试只获取文本节点(使用text()节点测试):

>>> for h2 in selector.css('h2.video'):
...     print(h2.xpath('text()').extract())
... 
['\n']

更糟糕的是,我们没有在<i>元素中获取文本节点。(实际上,text()只选择直接子文本节点,而不是子节点的子节点)

让我们试试.//,也就是./descendant-or-self::node()/快捷方式:

>>> for h2 in selector.css('h2.video'):
...     print(h2.xpath('.//text()').extract())
... 
['\n', 'Mjadra']

不比使用XPath的string()好多少。在

现在,让我们使用node()节点测试,捕获元素和文本节点:

>>> for h2 in selector.css('h2.video'):
...     print(h2.xpath('node()').extract())
... 
['<img src="content/pl_makingfood_mjadrah.jpg" alt="Thumbnail image from video" width="160" height="120">', '<br>', '<br>', '\n', '<i>Mjadra</i>']

这更好,但是我们有这些<img>标记,您可能不想要。所以我们只选择文本节点和<i>s:

>>> for h2 in selector.css('h2.video'):
...     print(h2.xpath('./node()[self::text() or self::i]').extract())
... 
['\n', '<i>Mjadra</i>']
>>> 

您可能需要从每个标题中提取一个字符串。因此,使用Python的join()是一个选项:

>>> for h2 in selector.css('h2.video'):
...     print( "".join(h2.xpath('./node()[self::text() or self::i]').extract()) )
... 

<i>Mjadra</i>
>>> 

在元素上调用text()时,只获得顶层文本节点,而您也希望向下到每个子元素,请使用.//text()

rawTitles = response.xpath('//h2[@class="video"]//text()').extract()

然后,您可以使用str.join()rawTitles列表中的项连接起来,但我建议您查看Item Loaders和输入和输出处理器—在这种情况下,Join()处理器是合适的。在

或者,按照Paul在注释中的建议,使用^{}XPath函数:

^{pr2}$

相关问题 更多 >