2017-07-17 3 views
0

私はScrapyを使用してビジネスディレクトリをスクラップしています。私はFacebookとTwitterのリンクをつかみたいと思う場所をいくつか持っています。しかし、毎回FacebookやTwitterのリンクがあるとは限りません。コードを使用して、私は今それを完全にスキップします。Scrapyを使用すると、データが返されないときに空の文字列を入力するにはどうすればよいですか?

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(), 
     } 

これらの情報がある場合は保存しておきますが、保存しない場合は空白の文字列を残しておきたいと思います。私はこれを行うには最高の方法は何ですか?

答えて

1

socialリストのIndexErrorのためにスキップしていますか?そのような場合、私はこのようなログインfacebook/Twitterに別々の変数にその最大分割を試してみた:

social = response.css('.entry-content > div:nth-child(2) a::attr(href)').extract() 
try: 
    facebook = social[0] 
except IndexError: 
    facebook = '' 

代替方法:

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, '') 
+0

:私の場合には(私はそれが空白になりたかった場所)、私はこれを使用していました。しかし、私は別の問題に取り組んでいます。行方不明の変数が4〜5つ以上あるようです。 try/exceptsの束を持つことは非常に面倒です。これを回避する簡単な方法は何ですか? – Lewis

+0

そうです、わかりました。私はおそらく別の関数にそれを抽出するだろう。変数ごとに2行に制限したい場合は 'len(social)> = 1:facebook = social [0]' –

+0

これはもう一つの方法です。既にresponse.cssを 'social'に抽出したとします。 'social = dict(enumerate(social))'を実行し、必要に応じて 'social.get(0、 '')' –

1
それは解決策があるように私はコーリーマッデンの答えを任せるだろう

IndexErrorを取得するときに私の答えに。しかし、私が使用していたコードは常にエラーにつながることを認識しています。 .extract()機能を使用することは、のコンテンツが100%確実に存在する場合にのみ使用する必要があります。ビジネスディレクトリを使用した例:ウェブサイト、Facebook、またはTwitterになるとは必ずしも100%ではありません。代わりに、私はこれをしました:

私は絶対的なCSSセレクター(firefoxを使用している場合は、右クリック、コピー> CSSセレクター)を取り出して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='')

関連する問題