使用Scrapy,如何在没有返回数据时输入空白字符串?

时间:2017-07-17 01:13:50

标签: python scrapy

我正在使用Scrapy来抓取业务目录。我有几个领域,我想抓住他们的Facebook和Twitter链接。但是,并非每次都有Facebook或Twitter链接。使用我现在的代码,它只是完全跳过它们。

import scrapy
from scrapy import Request

# TODO: Find a way to scrape even if there is nothing there
# TODO: Find a way to scrape any extra information

class BDSpider(scrapy.Spider):
    name = "bd"
    start_urls = [
        'http://example.url',
    ]

    def parse(self, response):
        businesses = response.css('div.card-business')

        for business in businesses:
            relative_url = business.css('a::attr(href)').extract_first()
            absolute_url = response.urljoin(relative_url)


            yield Request(absolute_url, callback=self.parse_page, meta={'URL': absolute_url})


    def parse_page(self, response):
        url = response.meta.get('URL')

        # Parse the locations area of the page
        locations = response.css('address::text').extract()
        # Takes the City and Province and removes unicode and removes whitespace,
        # they are still together though.
        city_province = locations[1].replace(u'\xa0', u' ').strip()
        # List of all social links that the business has
        social = response.css('.entry-content > div:nth-child(2) a::attr(href)').extract()

        yield {
            'title' : response.css('h1.entry-title::text').extract_first().strip(),
            'description' : response.css('p.mb-double::text').extract_first(),
            'phone_number' : response.css('div.mb-double ul li::text').extract_first().strip(),
            'email' : response.css('div.mb-double ul li a::text').extract_first(),
            'address' : locations[0].strip(),
            'city' : city_province.split(' ', 1)[0].replace(',',''),
            'province' : city_province.split(' ', 1)[1].replace(',','').strip(),
            'zip_code' : locations[2].strip(),
            'website' : social[0],
            'facebook' : social[1],
            'twitter' : social[2],
            'linkedin' : social[3],
            'year' : response.css('.list-border > li:nth-child(1)::text').extract_first().strip(),
            'employees' : response.css('.list-border > li:nth-child(2)::text').extract_first().strip(),
            'key_contact' : response.css('.list-border > li:nth-child(3)::text').extract_first().strip(),
            'naics' : response.css('.list-border > li:nth-child(4)::text').extract_first().strip(),
            'tags' : response.css('ul.biz-tags li a::text').extract(),
        }

我想拥有它,以便如果他们有这些信息然后存储它,但如果没有,那么只留下一个空白字符串。我能做到这一点的最佳方式是什么?

2 个答案:

答案 0 :(得分:1)

是否由于social列表中的social = response.css('.entry-content > div:nth-child(2) a::attr(href)').extract() try: facebook = social[0] except IndexError: facebook = '' 而跳过它们?如果是这样的话,我会尝试将其拆分为facebook / twitter的单独变量,如下所示:

social = response.css('.entry-content > div:nth-child(2) a::attr(href)').extract()
social = dict(enumerate(social))
facebook = social.get(0, '')
twitter = social.get(1, '')

替代方法:

QList<QDate>

答案 1 :(得分:1)

我将离开Cory Madden的答案,因为它是获得IndexError时我的答案的解决方案。但是,我意识到我使用的代码总是会导致错误。这意味着只有在 100%确定将有内容存在时才使用.extract()功能。使用商业目录的示例:并非总是100%存在成为一个网站,Facebook或Twitter。所以我做了这个:

我选择了绝对的CSS选择器(右键单击,复制&gt; CSS Selector,如果您使用的是Firefox)并将其粘贴到response.css('')属性中。所以我的代码看起来像这样:

yield {
    # ...code goes here
    facebook = response.css('.entry-content > div:nth-child(2) > ul:nth-child(2) > li:nth-child(2) > a:nth-child(1)::attr(href)').extract_first(default=''),
    # ...code goes here
}

现在我没有使用tryexcept方法,而是使用extract_first()方法,您可以传递像default='no data was found'这样的参数。在我的情况下(我希望它是空白的),我使用了这个:

'facebook' : response.css(css_selector).extract_first(default='')