【问题标题】:How to extract text in python from div tag if other html is within the tag?如果标签内有其他html,如何从div标签中提取python中的文本?
【发布时间】:2019-05-22 14:28:13
【问题描述】:

我正在尝试提取参考。带有scrapy的HTML中的ID:

<div class="col" itemprop="description">
  <p>text Ref.&nbsp;<span>220.20.34.20.53.001</span></p>
  <p>more text</p>
</div>

span 和 p 标签并不总是存在。

使用 xpath 选择器:

text = ' '.join(response.xpath('//div[@itemprop="description"]/p/text()').extract()).replace(u'\xa0', u' ')
try: 
     ref_id = re.findall(r"Ref\.? ?((?:[A-Z\d\.]+)|(?:[\d.]+))", text)[0].strip()

在这种情况下只返回一个空字符串,因为标签内有 HTML。

现在尝试使用 CSS 选择器提取文本以使用 remove_tags:

>>> ''.join([remove_tags(w).strip()for w in response.css('div[itemprop="description"]::text').extract()]) 

这会返回一个空结果,因为我无法获取该项目。

无论是否在 div 中包含 html &lt;p&gt; 标签,我如何提取 ref_id。爬取的某些项目没有&lt;p&gt; 标签,也没有&lt;span&gt;,这是我第一次尝试使用xpath 的地方。

【问题讨论】:

  • 我假设你知道著名的RegEx match open tags except XHTML self-contained tags?你为什么不使用 BeautifulSoup?
  • 不,没见过那个。我认为scrapy不需要漂亮的汤,因为它可以使用内置的css和xpath选择器处理这样的任务?
  • 可能(我对这个库不是很熟悉),但你很清楚地将正则表达式模块混入其中。
  • 是的,一旦我从 div 中获得了文本,我将使用正则表达式从文本中提取 ref id。这适用于 90% 的情况,除了文本中有附加 标记的情况。
  • 这正是我链接的答案在一般情况下试图说明的内容;不要在 HTML 上使用正则表达式,使用 HTML 解析器 :)

标签: python scrapy


【解决方案1】:

您不需要使用remove_tags,因为您可以通过选择器直接获取text

sel.css('div[itemprop=description] ::text')

这将从带有itemprop="description"div 标记中获取所有内部文本,稍后您可以使用正则表达式提取您的信息:

sel.css('div[itemprop=description] ::text').re_first('(?:\d+.)+\d+')

【讨论】:

  • 这实际上帮助了我,因为删除标签也删除了分隔符并删除了

    。您能否详细解释一下您使用 css 选择器的方式?我认为这将在您稍后获取第一个标签时每行返回一个标签。

  • 这里有趣的部分是选择器和::text 之间的space,它告诉选择器从内部元素中获取所有text,而不仅仅是当前元素(这将是div)。稍后Parsel 函数re_first 检查所有元素并获取第一个与指定正则表达式匹配的元素。
  • 感谢您的澄清。
【解决方案2】:

尝试从您的最后一个表达式中删除::text

''.join([remove_tags(w).strip() for w in response.css('div[itemprop=description]').extract()]) 

但如果您只需要从 html 中提取 220.20.34.20.53.001,为什么不使用 response.css('div[itemprop=description] p span::text').extract()

甚至response.css('div[itemprop=description]').re(r'([\.\d]+)')

【讨论】:

  • 谢谢!这就是我一直在寻找的。我没有使用 p span .. 因为它只存在于 10% 的项目中,然后这将返回一个空结果。
  • 您对正则表达式的尝试很有趣,但是您的正则表达式返回所有数字并且存在更多数字。尝试将此适应我的正则表达式仅返回一个点: response.css('div[itemprop=description]').re(r'Ref\.? ?((?:[AZ\d\.]+)|( ?:[\d.]+))') 这是正确的语法吗?正则表达式应该没问题。
  • 如果您添加条件以数字开头,则可以正常工作:response.css('div[itemprop=description]').re(r'(\d[\.\d]+)')
  • 在你的正则表达式中,你应该避免依赖 Ref. 字符串,因为它在另一个标签正文中。
  • 参考。是唯一的共同元素,id 可能看起来完全不同。我现在用这个命令得到了一个结果: re.findall(r"Ref\.? ?((?:[AZ\d\.]+)|(?:[\d.]+))",remove_tags(response .css('div[itemprop=description]').extract_first()).replace(u'\xa0', u' ').strip())[0] 你看到这个查询可以做的任何改进吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-15
  • 1970-01-01
  • 2017-08-08
  • 2015-01-27
  • 2014-05-22
相关资源
最近更新 更多