2014-07-23 1 views
0

Вот что я хочу добиться:Как вернуться к функции разбора вызова при использовании урона в scrapy?

class Hello(Spider): 
    #some stuff 
    def parse(self, response): 
     #get a list of url of cities using pickle and store in a list 
     #Now for each city url I have to get list of monuments (using selenium) which is achieved by the below loops 
     for c in cities: 
      #get the list of monuments using selenium and iterate through each monument url contained in the division 
      divs = sel.xpath('some xpath/div') 
      for div in divs: 
       monument_url=''.join(div.xpath('some xpath')) 
       #For each monument url get the response and scrape the information 
       yield Request(monument_url, self.parse_monument) 
    def parse_monument(self, response): 
     #scrape some information and return to the loop(i.e. return to "for div in divs:") 

Теперь, что происходит это: 1. Я получаю список всех памятников во всем городе до исполнения заявления выхода.
2. Всякий раз, когда выполняется инструкция yield, она переходит в функцию parse_monument и не возвращается обратно в цикл, только очищая список памятника, который присутствует в первом городе.

Есть ли способ сделать это? Есть ли способ получить объект ответа, который запрашивает метод, передается в parse_monument, не переходя к методу parse_monument, чтобы я мог использовать селекторы для выбора элементов, которые мне нужны из ответа?

спасибо!

+0

Добавить некоторые 'print' перед' yield' и 'parse_monument', чтобы увидеть, как это работает. – furas

+0

То же, что я упомянул ранее. Перед выходом 1-й и 2-й в parse_monument. – Rahul

ответ

0

Я не думаю, что вы можете вызвать функцию, как вы. Вот рефакторинг:

class HelloSpider(scrapy.Spider): 
    name = "hello" 
    allowed_domains = ["hello.com"] 
    start_urls = (
     'http://hello.com/cities' 
    ) 

    def parse(self, response): 
     cities = ['London','Paris','New-York','Shanghai'] 
     for city in cities: 
      xpath_exp= 'some xpath[city="' + city + '"]/div/some xpath' 
      for monument_url in response.xpath(xpath_exp).extract(): 
       yield Request(monument_url, callback=self.parse_monument) 

    def parse_monument(self,response): 
     pass 
0

Request является объектом, а не метод. Scrapy обрабатывает полученный объект Request и выполняет обратный вызов асинхронно. Вы можете просмотреть запрос как объект потока.

Решение заключается в обратном, вы передаете данные, которые вам нужны, из метода parse вместо запроса, поэтому вы можете обрабатывать их внутри parse_monument.

class Hello(Spider): 

    def parse(self, response): 
     for c in cities: 
      divs = sel.xpath('some xpath/div') 
      for div in divs: 
       monument_url=''.join(div.xpath('some xpath')) 

       data = ... # set the data that you need from this loop 

       # pass the data into request's meta 
       yield Request(monument_url, self.parse_monument, meta={'data': data}) 

    def parse_monument(self, response): 
     # retrieve the data from response's meta 
     data = response.meta.get('data') 
     ... 
Смежные вопросы