【问题标题】:Scrapy: Unable to get the output file in proper formatScrapy:无法以正确的格式获取输出文件
【发布时间】:2017-05-10 16:42:50
【问题描述】:

我将输出作为连续数据在行中而不是以正确的记录格式显示(每行一条记录)。这是我的代码:

import scrapy
from scrapy.contrib.spiders import CrawlSpider, Rule
from scrapy.contrib.linkextractors import LinkExtractor
class famousPeopleItem(scrapy.Item):
# define the fields for your item here like:
    Name = scrapy.Field()
    Profession = scrapy.Field()
    Birth_Date = scrapy.Field()
    Birth_Place = scrapy.Field()
    Nationality = scrapy.Field()
    Died_On = scrapy.Field()
    # item class included here 
    class famousPeople(CrawlSpider):
    name = 'famous'
     start_urls = [
       'http://www.thefamouspeople.com/famous-people-by-zodiac-sign.php'
        ]
     custom_settings = {
           'DEPTH_LIMIT': '1',
       }
    rules = (
      Rule(LinkExtractor(restrict_xpaths=
     ('//div[@class="table_list"]//a',)),callback='parse_item',follow=True),
    )
    def parse_item(self, response):
     item = famousPeopleItem()
     item["Name"] = 
     response.xpath('//div[@class="section"]//a[2]//text()').extract()
     item["Profession"] = 
     response.xpath('//div[@class="section"]//span//text()').extract()
     item["Birth_Date"] = 
     response.xpath('//div[@class="section"]//p[1]//text()').extract()
     item["Birth_Place"] = 
     response.xpath('//div[@class="section"]//p[2]//text()').extract()
     item["Nationality"] = 
     response.xpath('//div[@class="section"]//p[3]//text()').extract()
     item["Died_On"] = 
     response.xpath('//div[@class="section"]//p[4]//text()').extract()
     yield (item)

虽然 extract_first() 有助于以正确的格式提供数据,但它不会获取所有记录。

【问题讨论】:

  • 你想如何显示你的输出?
  • 在csv文件中,每行一条记录。

标签: python-2.7 web-scraping scrapy


【解决方案1】:

要获得每行一条记录,您需要每人产生一项。

目前您生成一个(大)项目,其中所有数据都被提取到您的字段中。这是因为您的 XPath 选择器涵盖了页面上的所有人。

您需要一个跨越单身人士的选择器,而不是 response.xpath('//div[@class="section"]')。在 html 代码中搜索合适的标签。看起来tile 更有希望。

然后你应该遍历那个新的selector 并通过以点开头使你的项 XPaths 相对于父选择器。最后每人产出一件物品。

伪代码如下:

def parse_item(self, response):
    sel_persons = response.xpath('//div[@class="tile"]')
    for sel_person in sel_persons:
        # ...
        item['Name'] = sel_person.xpath('.//a[2]//text()').extract_first()
        # ...
        yield item

另见scrapy的文档和Working with relative XPaths部分

【讨论】:

    【解决方案2】:

    extract() 将抓取的数据作为(unicode)字符串列表返回。如果您想要所有数据而不仅仅是第一个元素,您可以将结果连接到一个字符串中,如下所示:

    SEPARATOR = ' '
    
    item["Name"] = SEPARATOR.join(response.xpath('//div[@class="section"]//a[2]//text()').extract())
    # ... and so on
    

    (我在这里假设可以只用空格分隔各个部分 - 如果“|”或“,”等不同的分隔符更适合您的目的,请调整它)。

    如果你想做更复杂的提取操作,比如过滤特定片段、剥离等,我建议你看看 Scrapy 的项目加载器:https://doc.scrapy.org/en/latest/topics/loaders.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-18
      • 2014-10-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多