0

これは私が今朝の別の質問をしたのと同じコードを含んでいます。Scrapyが設定されたリストは実際に返される前に返されます

class LbcSubtopicSpider(scrapy.Spider): 

...irrelevant/sensitive code... 

    rawTranscripts = [] 
    rawTranslations = [] 

    def parse(self, response): 
     rawTitles = [] 
     rawVideos = [] 
     for sel in response.xpath('//ul[1]'): #only scrape the first list 

      ...irrelevant code... 

      index = 0 
      for sub in sel.xpath('li/ul/li/a'): #scrape the sublist items 
       index += 1 
       if index%2!=0: #odd numbered entries are the transcripts 
        transcriptLink = sub.xpath('@href').extract() 
        #url = response.urljoin(transcriptLink[0]) 
        #yield scrapy.Request(url, callback=self.parse_transcript) 
       else: #even numbered entries are the translations 
        translationLink = sub.xpath('@href').extract() 
        url = response.urljoin(translationLink[0]) 
        yield scrapy.Request(url, callback=self.parse_translation) 

     print rawTitles 
     print rawVideos 
     print "translations:" 
     print self.rawTranslations 

    def parse_translation(self, response): 
     for sel in response.xpath('//p[not(@class)]'): 
      rawTranslation = sel.xpath('text()').extract() 
      rawTranslation = ''.join(rawTranslation) 
      #print rawTranslation 
      self.rawTranslations.append(rawTranslation) 
      #print self.rawTranslations 

私の問題はparse(...)法における「印刷self.rawTranslationsが」"[]"以上のものを印刷していないということです。これは2つのうちの1つを意味する可能性があります。つまり、印刷直前にリストをリセットしている可能性があります。parse_translation(...)への呼び出しが完了してから、parse(...)のリンクのリストが読み込まれます。クラスボディの"rawTranslations = []"が複数回実行されない限り、リストをリセットするコードが見つからないため、後者の疑いがあります。

parse_translation(...)の同じ行のコメントを外すと、適切なテキストが出力されます。つまり、テキストが正しく抽出されており、その問題はメインのparse(...)メソッドに固有のようです。

私が同期の問題だと思っているものを解決しようとする試みは、まったく目的がありませんでした - 私は見つけることができる多くのGoogleチュートリアルに基づいてRLockオブジェクトを使用しようとしました。結果は同一であった。

+0

私は過去1時間にインターネットを掘り下げて、Pythonのロックをよく理解し、それほど遠くに進まないよう努めてきました。私の頭の中にあるアイデアは、最後のサブページの訪問が完了したらロックを解除することですが、驚くほどシンタックスの例はほとんど見つかりませんでした。 – jah

答えて

0

だからこれは私がちょうどScrapyの要求の優先順位を知った、特に以来、多少ハックソリューションのように思えます

class LbcVideosSpider(scrapy.Spider): 

    ...code omitted... 

    done = 0 #variable to keep track of subtopic iterations 
    rawTranscripts = [] 
    rawTranslations = [] 

    def parse(self, response): 
     #initialize containers for each field 
     rawTitles = [] 
     rawVideos = [] 

     ...code omitted... 

      index = 0 
      query = sel.xpath('li/ul/li/a') 
      for sub in query: #scrape the sublist items 
       index += 1 
       if index%2!=0: #odd numbered entries are the transcripts 
        transcriptLink = sub.xpath('@href').extract() 
        #url = response.urljoin(transcriptLink[0]) 
        #yield scrapy.Request(url, callback=self.parse_transcript) 
       else: #even numbered entries are the translations 
        translationLink = sub.xpath('@href').extract() 
        url = response.urljoin(translationLink[0]) 
        yield scrapy.Request(url, callback=self.parse_translation, \ 
         meta={'index': index/2, 'maxIndex': len(query)/2}) 

     print rawTitles 
     print rawVideos 

    def parse_translation(self, response): 
     #grab meta variables 
     i = response.meta['index'] 
     maxIndex = response.meta['maxIndex'] 

     #interested in p nodes without class 
     query = response.xpath('//p[not(@class)]') 
     for sel in query: 
      rawTranslation = sel.xpath('text()').extract() 
      rawTranslation = ''.join(rawTranslation) #collapse each line 
      self.rawTranslations.append(rawTranslation) 

      #increment number of translations done, check if finished 
      self.done += 1 
      print self.done 
      if self.done==maxIndex: 
       print self.rawTranslations 

基本的に、私は多くの要求が完了したかの追跡を維持し、FINAているリクエストに応じていくつかのコードが条件付き作る:機能が、ここでは、所望の結果を与える私の新しいコードですl。完全に入力されたリストが印刷されます。

0

ここで問題となっているのは、scrapyが実際にどのように機能するか理解できていないことです。

Scrapyはクロールフレームワークで、リクエストを行うだけでなく、ウェブサイトのスパイダーを作成するために使用されます。これはrequestsモジュールです。

Scrapyの要求は非同期に処理されます。yield Request(...)に電話すると、ある時点で実行される要求のスタックに要求を追加しています(制御できません)。つまり、yield Request(...)のコードがその時点で実行されることを期待することはできません。実際には、メソッドは常に終了する必要がありますRequestまたはItem

私が見ることができ、ほとんどの場合、治療と混乱する場合は、作成したアイテムに何らかの方法で作成したアイテムを埋め込みたいのですが、必要な情報は別の要求です。その場合には

は、通信は通常Requestmetaパラメータで行われ、このような何か:

... 
    yield Request(url, callback=self.second_method, meta={'item': myitem, 'moreinfo': 'moreinfo', 'foo': 'bar'}) 

def second_method(self, response): 
    previous_meta_info = response.meta 
    # I can access the previous item with `response.meta['item']` 
    ... 
+0

これは状況がどのくらい変わっているのか分かりませんが、移入しようとしているアイテムはメソッドではなく、クラス内のオブジェクトとして作成されています。 – jah

+0

メタ情報がこれを行う方法であるとは思われません。少なくとも、すべてをどのように構成したかではありません。その理由は、 'parse'または' parse_translation'のいずれかから別の要求しか出せないため、どちらのメソッドも 'self.rawTranslations'を完全な状態で渡すことができないからです。私が 'parse'でそれを行うとすれば、空のリストを渡します。私が 'parse_translation'でそれを行うとすれば、最後に一度だけではなく、リスト項目があるように何回も私の(未書き込みの)メソッドを呼び出すでしょう。私はこれがメソッドの外にあるコンテナと関係していると思います。 – jah

関連する問題