【问题标题】:Code to remove text from Scrapy output从 Scrapy 输出中删除文本的代码
【发布时间】:2016-03-12 14:24:43
【问题描述】:

下面是一段我想用 scrapy 抓取的 HTML 代码示例。

<body>
<h2 class="post-title entry-title">Sample Header</h2>
    <div class="entry clearfix">
        <div class="sample1">
            <p>Hello</p>
        </div>
        <!--start comment-->
        <div class="sample2">
            <p>World</p>
        </div>
        <!--end comment-->
    </div>
<ul class="post-categories">
<li><a href="123.html">Category1</a></li>
<li><a href="456.html">Category2</a></li>
<li><a href="789.html">Category3</a></li>
</ul>
</body>

现在我正在使用下面的scrapy代码:

from scrapy.contrib.spiders import CrawlSpider, Rule
from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor
from scrapy.selector import HtmlXPathSelector
from isbullshit.items import IsBullshitItem

class IsBullshitSpider(CrawlSpider):
    name = 'isbullshit'
    start_urls = ['http://sample.com']
    rules = [Rule(SgmlLinkExtractor(allow=[r'page/\d+']), follow=True), 
        Rule(SgmlLinkExtractor(allow=[r'\w+']), callback='parse_blogpost')]

    def parse_blogpost(self, response):
        hxs = HtmlXPathSelector(response)
        item = IsBullshitItem()
        item['title'] = hxs.select('//h2[@class="post-title entry-title"]/text()').extract()[0]
        item['tag'] = hxs.select('//ul[@class="post-categories"]/li[1]/a/text()').extract()[0]
        item['article_html'] = hxs.select("//div[@class='entry clearfix']").extract()[0]
        return item

它给了我以下 xml 输出:

<?xml version="1.0" encoding="utf-8"?>
<items>
    <item>

        <article_html>
        <div class="entry clearfix">
        <div class="sample1">
            <p>Hello</p>
        </div>
        <!--start comment-->
        <div class="sample2">
            <p>World</p>
        </div>
        <!--end comment-->
        </div>      
        </article_html>

        <tag>
        Category1
        </tag>

        <title>
        Sample Header
        </title>

    </item>
</items>

我想知道如何实现如下输出:

<?xml version="1.0" encoding="utf-8"?>
<items>
    <item>

        <article_html>
        <div class="entry clearfix">
        <div class="sample1">
            <p>Hello</p>
        </div>
        <!--start comment-->
        <!--end comment-->
        </div>      
        </article_html>

        <tag>
        Category1,Category2,Category3
        </tag>

        <title>
        Sample Header
        </title>

    </item>
</items>

注意:类别的数量取决于帖子。在上面的示例中,有 3 个类别。可能更多也可能更少。

我们将不胜感激。 干杯。

【问题讨论】:

    标签: python html regex web-scraping scrapy


    【解决方案1】:
    sel = Selector(text=u"<div class="entry clearfix">
        <div class="sample1">
            <p>Hello</p>
        </div>
        <!--start comment-->
        <div class="sample2">
            <p>World</p>
        </div>
        <!--end comment-->
    </div>")
    total = sel.xpath('//div[@class="entry clearfix"]').extract_first()
    

    第一部分

    unwanted_part = sel.xpath('//div[@class="sample2"]').extract_first()
    new_total = total.replace(unwanted_part, '')
    

    第二部分

    comments = sel.xpath('//div[@class="entry clearfix"]/comment()').extract()
    new_total = total
    for comment in comments:
        new_total = new_total.replace(comment, '')
    

    我认为这不能仅使用 xpath 或 css 来完成。

    【讨论】:

      【解决方案2】:

      这不是scrapy 的选择器的工作。如果你想操作一个 DOM,你最好使用BeautifulSoup

      from bs4 import BeautifulSoup
      
      [...]
      
      item = hxs.select("//div[@class='entry clearfix']").extract()[0]
      
      # Removing div#sample1
      soup = BeautifulSoup(item)
      
      # Select supports CSS selection
      tags = soup.select('div.sample1')[0]  # Assume at least one element found
      
      tags[0].extract()  # remove element in-place
      
      sub_total = soup.div.encode()
      

      第二个有点小技巧,因为无法使用extracts,但这是另一种选择:

      soup = BeautifulSoup(item)
      
      temp = soup.div.div.extract()  # Get inner tag of interest
      
      soup.div.clear()  # Remove all children tags
      
      soup.div.append(temp)  # Insert temp tag
      
      sub_total = soup.div.encode()
      

      我知道这感觉过于手动和冗长,但至少是另一种选择。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-09-18
        • 2015-10-11
        • 2015-03-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多