2017-04-04 7 views
0

Facebook APIを使用してウェブサイトのすべてのページのお気に入りを計算するスパイダーを作成したいとします。リクエストライブラリをインポートすると、次のようにFacebookグラフAPIを呼び出すことができます。外部APIを呼び出すためのベストプラクティスは何ですか?

import scrapy 
import json 
import requests 

API_KEY="KEY_GOES_HERE" 

class WebSite(scrapy.Spider): 
    name = "website_page" 
    allowed_domains = ["website.com"] 
    start_urls = ['https://website.com/'] 
    def get_likes(self,url): 
     base='https://graph.facebook.com/{}?access_token={}'.format(url,API_KEY) 
     data=requests.get(base) 
     return self.parse_likes(data) 
    def parse_likes(self, data): 
     data = json.loads(data.text) 
     return data['id'],data['share']['comment_count'],data['share']['share_count'] 

    def parse(self, response): 
     item= {} 
     item['url'] = response.url 
     links = response.css('a::attr(href)').extract() 
     item['fb_url'],item['shares'],item['comments'] = self.get_likes(response.url) 
     for link in links: 
      link = response.urljoin(link) 
      item['link'] = link 
      yield scrapy.Request(link, callback=self.parse) 
     yield item 

しかし、私はむしろ要求を使用するよりも、私はscrapy.Request呼び出しを使用し、場合には、このコードが動作するように見えることはできません。このようなもの。

import scrapy 
import json 
import requests 

API_KEY="KEY_GOES_HERE" 

class WebSite(scrapy.Spider): 
    name = "website_page" 
    allowed_domains = ["website.com"] 
    start_urls = ['https://website.com/'] 
    def get_likes(self,url): 
     base='https://graph.facebook.com/{}?access_token={}'.format(url,API_KEY) 
     return scrapy.Request(base,callback=self.parse_likes) 
    def parse_likes(self, data): 
     data = json.loads(data.text) 
     return data['id'],data['share']['comment_count'],data['share']['share_count'] 

    def parse(self, response): 
     item= {} 
     links = response.css('a::attr(href)').extract() 
     item['url'] = response.url 
     item['fb_data']=self.get_likes(response.url).body 
     for link in links: 
      link = response.urljoin(link) 
      item['link'] = link 
      yield scrapy.Request(link, callback=self.parse) 
     yield item 

この場合、Facebookデータに対して空白の応答が表示されます。私は、scrapy.Requestメソッドが標準のリクエストライブラリに対してどのように機能するかについて、いくつかの理解が不足していると思います。何か案は?

答えて

2

これは非常に一般的なケースです。複数のURLからアイテムを取得する方法は?
そして、最も一般的な解決策は、request.metaパラメーターでアイテムを運ぶことでチェーンリクエストになります。だから私はこの作業を得ている

class WebSite(scrapy.Spider): 
    base='https://graph.facebook.com/{}?access_token={}'.format 
    api_key = '1234' 

    def parse(self, response): 
     links = response.css('a::attr(href)').extract() 
     for link in links: 
      item= {} 
      item['url'] = response.url 
      item['fb_data']=self.get_likes(response.url).body 
      item['link'] = response.urljoin(link) 
      api_url = self.base(self.api_key, link) 
      yield scrapy.Request(api_url, 
           callback=self.parse_likes, 
           meta={'item': item}) 

    def parse_likes(self, response): 
     item = response.meta['item'] 
     data = json.loads(data.text) 
     share_count = data['id'],data['share']['comment_count'],data['share']['share_count'] 
     item['share_count'] = share_count 
     yield item 
+0

:?このロジックを使用して実装例は次のようになり可能性があるため

1つの迅速なフォローアップ。複数のAPISを呼びたい場合は、parse_likesからparse_tweetsへのチェーンが必要ですか、またはAPIリクエストを並行して実行する方法がありますか? – user1507889

+0

チェーン自体は、すべてのリンクが前のリンクを終了する必要があるため、同時性はありませんが、スパイダの残りの部分は同時に実行されているため、同時性の問題はありません。だからあなたが20のウェブサイトをクロールしているならば、すべてのチェーンは互いに非同期になりますが、それ自体では同期的です。並行チェーンを持つ方法はまったくありませんが、通常は実装の面倒なことにはなりませんが、関心がある場合は、パイプラインとその中で要求をスケジュールする方法を検討する必要があります。 – Granitosaurus

関連する問題