Scrapy:无法以正确的格式获取输出文件

时间:2017-05-10 06:51:59

标签: python-2.7 web-scraping scrapy

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

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()有助于以适当的格式提供数据,但它不会获取所有记录。

2 个答案:

答案 0 :(得分: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

部分

答案 1 :(得分:0)

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