2017-12-24 28 views
1

すべてのイベントデータをhttp://www.nyhistory.org/programs/upcoming-public-programsから削り取りたいと思います。イベントはページごとに5つのイベントにページが分けられます。次のページに進むルールと、イベントの詳細ページに従うルールの2つのルールを作成しました。だから、私はスパイダーが最初に各イベントのURLを入力し、そこから必要なすべてのデータを収集し、次のページに進み、各イベントのURLなどを入力することを期待します。しかし何らかの理由で私のSpiderは各ページから1つのイベントにしかアクセスせず、それが最初のイベントです。 、CrawlSpiderを使用しているとき、あなたはあなたが実際にアイテムのために手に入れたいものを見つける「まで、」それぞれのリンクを以下のために述べたようにルールがある治療スパイダーは1ページに1つのリンクしか持っていません

import scrapy 
from nyhistory.items import EventItem 
from scrapy.spiders import CrawlSpider, Rule 
from scrapy.linkextractors import LinkExtractor 
from datetime import datetime 
from w3lib.html import remove_tags 
from scrapy.selector import Selector 
import re 

class NyhistorySpider(CrawlSpider): 

    name = "events" 

    start_urls = ['http://www.nyhistory.org/programs/upcoming-public-programs',] 

    rules = [Rule(LinkExtractor(allow='.*?page=.*',restrict_xpaths='//li[@class="pager-next"]'), follow=True), 
      Rule(LinkExtractor(restrict_xpaths='//div[@class="view-content"]/div[contains(@class,"views-row")]'), callback='parse_event_details',follow=True), 
      ] 

    def parse_event_details(self, response): 

     base_url = 'http://www.nyhistory.org' 

     item = EventItem() 
     item['title'] = response.xpath('//div[@class="views-field-title"]//text()')[2].extract() 
     item['eventWebsite'] = response.url 

     details_area = response.xpath('//div[@class="body-programs"]') 
     details_area_str = " ".join(details_area.extract()) 
     details_area_str_split = re.split('EVENT DETAILS|LOCATION|PURCHASING TICKETS', details_area_str) 
     speakers_names_area = details_area_str_split[1] 
     speakersNames = Selector(text=speakers_names_area).xpath('strong').extract() 
     try: 
      item['speaker1FirstName'] = speakersNames[0].split()[0] 
      item['speaker1LastName'] = speakersNames[0].split()[1] 
     except: 
      item['speaker1FirstName'] = '' 
      item['speaker1LastName'] = '' 

     description = remove_tags(details_area_str_split[1]).strip() 
     item['description'] = description 

     try: 
      address_line = remove_tags(details_area_str_split[2]).strip() 
      item['location'] = address_line.split(',')[0] 
      item['city'] = address_line.split(',')[-2].strip() 
      item['state'] = address_line.split(',')[-1].split()[0] 
      item['zip'] = address_line.split(',')[-1].split()[1] 
      item['street'] = address_line.split(',')[1].strip() 
     except: 
      item['location'] = '' 
      item['city'] = '' 
      item['state'] = '' 
      item['zip'] = '' 
      item['street'] = '' 

     try: 
      item['dateFrom'] = self.date_converter(response.xpath('//span[@class="date-display-single"]/text()').extract_first(default='').rstrip(' - ')) 
     except: 
      try: 
       item['dateFrom'] = response.xpath('//span[@class="date-display-single"]/text()').extract()[1].split('|')[0] 
      except: 
       item['dateFrom'] = '' 
     try: 
      item['startTime'] = self.time_converter(response.xpath('//span[@class="date-display-start"]/text()')[1].extract()) 
      # item['endTime'] = self.time_converter(response.xpath('//span[@class="date-display-end"]/text()')[1].extract()) 
     except: 
      try: 
       item['startTime'] = self.time_converter(response.xpath('//span[@class="date-display-single"]/text()').extract()[1].split(' | ')[1]) 
      except: 
       item['startTime'] = '' 
     item['In_group_id'] = '' 
     try: 
      item['ticketUrl'] = base_url + response.xpath('//a[contains(@class,"btn-buy-tickets")]/@href').extract_first() 
     except: 
      item['ticketUrl'] = '' 
     item['eventImage'] = response.xpath('//div[@class="views-field-field-speaker-photo-1"]/div/div/img/@src').extract_first(default='') 
     item['organization'] = "New York Historical Society" 

     yield item 

    @staticmethod 
    def date_converter(raw_date): 
     try: 
      raw_date_datetime_object = datetime.strptime(raw_date.replace(',',''), '%a %m/%d/%Y') 
      final_date = raw_date_datetime_object.strftime('%d/%m/%Y') 
      return final_date 
     except: 
      raw_date_datetime_object = datetime.strptime(raw_date.replace(',','').replace('th','').strip(), '%a %B %d %Y') 
      final_date = raw_date_datetime_object.strftime('%d/%m/%Y') 
      return final_date 
    @staticmethod 
    def time_converter(raw_time): 
     raw_time_datetime_object = datetime.strptime(raw_time, '%I:%M %p') 
     final_time = raw_time_datetime_object.strftime('%I:%M %p') 
     return final_time 

答えて

1

の下に私のコードを参照してください。

しかし、スパイダー(またはルール)はいつ停止するかを知っていますか?これは、callbackfollowという属性を使用するためです。 callbackを使用している場合は、followcallbackはそのリンクを応答として処理する必要があるため、followを使用しているので、不要な場合は不要です)callback新しいリンクの探求を続ける。

より良いルールを定義し、followにするルールとcallbackに返すルールを指定する必要があります。

+0

ありがとうございました!あなたの提案にしたがって、私は以下のように自分のコードを変更し、今すぐ動作します! (LinkExtractor(restrict = xpaths = '// pause-next') '))、ルール(LinkExtractor(restrict = xパス)=' (@class、 "views-row")])、コールバック= 'parse_event_details')、] = '// div [@ class = "view-content" –

関連する問題