2016-07-02 13 views
0

私はこのバグに完全に困惑しています。私はこのページのすべてのメニュー項目を引き抜こうとしていますhttps://www.alloresto.fr/restaurant-livraison-a-domicile/restaurant/pizza-mia/angers-centre-ville/particuliers/carte。最も内側のforループに到達すると、それは1回の繰り返しを経て、次に移動します。これは非常に予期せぬことであり、何が原因なのか分かりません。このページを解析するための関数は次のとおりです。forループは反復しません

def get_menu(self, response): 
    image_url = response.urljoin(response.xpath('//span/img/@src').extract_first()) 
    for menu_section in response.xpath("//div[@id = 'contenu_choixplats']/div"): 
     menu_section_name = menu_section.xpath('dl/dt/text()').extract_first() 
     for menu_item in menu_section.xpath('ul/li'): 
      item = Restaurant() 
      item['restaurant_url'] = response.url 
      item['restaurant_name'] = response.request.meta['restaurant_name'] 
      item['street_name'] = response.request.meta['street_name'] 
      item['street_number'] = response.request.meta['street_number'] 
      item['city'] = response.request.meta['city'] 
      item['zip_code'] = response.request.meta['zip_code'] 
      item['food_type'] = response.request.meta['food_type'] 
      item['image_urls'] = [image_url] 
      item['menu_category'] = menu_section_name 
      item['menu_item_title'] = menu_item.xpath('div/h3/text()').extract() 
      item['menu_item_details'] = menu_item.xpath('div/p/text()').extract_first() 
      item['menu_item_price'] = menu_item.xpath('div').css('div.product-price-with-offer').xpath('p/text()').extract_first() 
      yield item 

私が紛失しているものはありますか?あなたの時間をありがとう。

--UPDATE ---

これは完全なコードです。私は、問題がget_menu関数の外にある場合に備えています。 get_menu関数は、ウェブサイトのインデックスから2ページ分を掘り下げた後にのみ見つかることに注意してください。 french_scraping.itemsから 再 スパイダー/ alloresto_spider.py 輸入scrapy インポートはレストラン

class DmozSpider(scrapy.Spider): 
    name = "alloresto" 
    allowed_domains = ['alloresto.fr'] 
    start_urls = ["https://www.alloresto.fr/livraison/villes/"] 

    def parse(self, response): 
     for sel in response.xpath('//ul/li/a/@href'): 
      url = response.urljoin(sel.extract()) 
      yield scrapy.Request(url, callback=self.restaurants_for_this_city) 

    def restaurants_for_this_city(self, response): 
     for restaurant in response.xpath('//article/div'): 
      restaurant_url = response.urljoin(restaurant.xpath('a/@href').extract_first()) 
      restaurant_name = restaurant.xpath('div/section[@class="restaurantDetails"]/h3/a/text()').extract_first() 
      full_address = restaurant.xpath('div/section[@class="restaurantDetails"]/address/text()').extract_first() 
      extracts = re.search(r'^([\d-]*?)\W(.*?),\W(.*?)\W(\d\d\d\d\d)', full_address) 
      try: 
       street_number = extracts.group(1) 
      except: 
       continue 
      street_name = extracts.group(2) 
      city = extracts.group(3) 
      zip_code = extracts.group(4) 
      food_type = restaurant.xpath('div/section/p').css('.restaurantCuisines').xpath('text()').extract() 
      meta_data = { 
       'restaurant_url': restaurant_url, 
       'restaurant_name': restaurant_name, 
       'street_number': street_number, 
       'street_name': street_name, 
       'city': city, 
       'zip_code': zip_code, 
       'food_type': food_type} 
      yield scrapy.Request(restaurant_url, meta=meta_data, callback=self.get_menu) 
     # get info on next page 
     next_page = response.css('.next').xpath('a/@href').extract() 
     if len(next_page) > 0: 
      url = response.urljoin(next_page[0]) 
      yield scrapy.Request(url, callback=self.restaurants_for_this_city) 

    def get_menu(self, response): 
     image_url = response.urljoin(response.xpath('//span/img/@src').extract_first()) 
     for menu_section in response.xpath("//div[@id = 'contenu_choixplats']/div"): 
      menu_section_name = menu_section.xpath('dl/dt/text()').extract_first() 
      for menu_item in menu_section.xpath('ul/li'): 
       item = Restaurant() 
       item['restaurant_url'] = response.url 
       item['restaurant_name'] = response.request.meta['restaurant_name'] 
       item['street_name'] = response.request.meta['street_name'] 
       item['street_number'] = response.request.meta['street_number'] 
       item['city'] = response.request.meta['city'] 
       item['zip_code'] = response.request.meta['zip_code'] 
       item['food_type'] = response.request.meta['food_type'] 
       item['image_urls'] = [image_url] 
       item['menu_category'] = menu_section_name 
       item['menu_item_title'] = menu_item.xpath('div/h3/text()').extract() 
       item['menu_item_details'] = menu_item.xpath('div/p/text()').extract_first() 
       item['menu_item_price'] = menu_item.xpath('div').css('div.product-price-with-offer').xpath('p/text()').extract_first() 
       yield item 

items.py

import scrapy 

class Restaurant(scrapy.Item): 
    # define the fields for your item here like: 
    # name = scrapy.Field() 
    restaurant_url = scrapy.Field() 
    street_number = scrapy.Field() 
    restaurant_name = scrapy.Field() 
    street_name = scrapy.Field() 
    city = scrapy.Field() 
    zip_code = scrapy.Field() 
    food_type = scrapy.Field() 
    menu_category = scrapy.Field() 
    menu_item_title = scrapy.Field() 
    menu_item_details = scrapy.Field() 
    menu_item_price = scrapy.Field() 
    image_urls = scrapy.Field() 
    images = scrapy.Field() 
    pass 

settings.py

BOT_NAME = 'french_scraping' 
SPIDER_MODULES = ['french_scraping.spiders'] 
NEWSPIDER_MODULE = 'french_scraping.spiders' 
ROBOTSTXT_OBEY = True 
ITEM_PIPELINES = {'scrapy.pipelines.images.ImagesPipeline': 1} 
IMAGES_STORE = '/Users/drew/Desktop/frenchscraping/french_scraping' 

pipelines.py

をインポート
class FrenchScrapingPipeline(object): 
    def process_item(self, item, spider): 
     return item 
+0

ジェネレータを返すようです:[yieldキーワードはPythonで何をしますか?](http://stackoverflow.com/questions/231767/what-does-the-yield-keyword-do-in-python ) – nlloyd

+1

私たちは関数を持っていますが、どのように呼び出されますか? [mcve]を入力してください。私はコールに問題があると思う。 –

+0

私は編集を行いました。上記の完全なコードをご覧ください。 – DrewSSP

答えて

0

get_menu(self、response)は、yield文を使用するため、ジェネレータです。

ジェネレータ関数が呼び出されると、関数の実行を開始せずにジェネレータオブジェクトを返します。コードを実行するには、 'for'ループ内でget_menu(self、response)を使用するか、反復する関数または構造体に渡す必要があります。

関連する問題