2011-07-06 10 views
8

Después de varias lecturas en documentos de Scrapy, todavía no veo la diferencia entre usar las reglas de CrawlSpider e implementar mi propio mecanismo de extracción de enlaces en el método de devolución de llamada.Enlaces siguientes, marco de rastreo de web de Scrapy

Estoy a punto de escribir un nuevo rastreador web usando el último enfoque, pero simplemente porque tuve una mala experiencia en un proyecto anterior al usar reglas. Realmente me gustaría saber exactamente lo que estoy haciendo y por qué.

¿Alguien familiarizado con esta herramienta?

Gracias por su ayuda!

Respuesta

10

CrawlSpider hereda BaseSpider. Simplemente agregó reglas para extraer y seguir enlaces. Si estas reglas no son lo suficientemente flexibles para usted - el uso BaseSpider:

class USpider(BaseSpider): 
    """my spider. """ 

    start_urls = ['http://www.amazon.com/s/?url=search-alias%3Dapparel&sort=relevance-fs-browse-rank'] 
    allowed_domains = ['amazon.com'] 

    def parse(self, response): 
     '''Parse main category search page and extract subcategory search link.''' 
     self.log('Downloaded category search page.', log.DEBUG) 
     if response.meta['depth'] > 5: 
      self.log('Categories depth limit reached (recursive links?). Stopping further following.', log.WARNING) 

     hxs = HtmlXPathSelector(response) 
     subcategories = hxs.select("//div[@id='refinements']/*[starts-with(.,'Department')]/following-sibling::ul[1]/li/a[span[@class='refinementLink']]/@href").extract() 
     for subcategory in subcategories: 
      subcategorySearchLink = urlparse.urljoin(response.url, subcategorySearchLink) 
      yield Request(subcategorySearchLink, callback = self.parseSubcategory) 

    def parseSubcategory(self, response): 
     '''Parse subcategory search page and extract item links.''' 
     hxs = HtmlXPathSelector(response) 

     for itemLink in hxs.select('//a[@class="title"]/@href').extract(): 
      itemLink = urlparse.urljoin(response.url, itemLink) 
      self.log('Requesting item page: ' + itemLink, log.DEBUG) 
      yield Request(itemLink, callback = self.parseItem) 

     try: 
      nextPageLink = hxs.select("//a[@id='pagnNextLink']/@href").extract()[0] 
      nextPageLink = urlparse.urljoin(response.url, nextPageLink) 
      self.log('\nGoing to next search page: ' + nextPageLink + '\n', log.DEBUG) 
      yield Request(nextPageLink, callback = self.parseSubcategory) 
     except: 
      self.log('Whole category parsed: ' + categoryPath, log.DEBUG) 

    def parseItem(self, response): 
     '''Parse item page and extract product info.''' 

     hxs = HtmlXPathSelector(response) 
     item = UItem() 

     item['brand'] = self.extractText("//div[@class='buying']/span[1]/a[1]", hxs) 
     item['title'] = self.extractText("//span[@id='btAsinTitle']", hxs) 
     ... 

Incluso si start_urls de BaseSpider no son lo suficientemente flexibles para que, anular start_requests método.

+0

¡Muchas gracias! No mencioné que estoy rastreando Amazon, así que diste un recurso increíblemente útil: D. Amazon tiene algunas URL que contienen un carácter hash, y Scrapy está eliminando la URL de ese signo hash hasta el final. ¿Si hay una forma de modificar este comportamiento y mantener toda la URL? T.I.A, aprecia tu ayuda. – romeroqj

+0

¿dónde está pelando? in request.url, selector xpath o? – warvariuc

+0

Creo un nuevo hilo para esto si no te importa consultar. http://stackoverflow.com/questions/6604690/scrapy-hash-tag-on-urls – romeroqj

1

Si desea un rastreo selectivo, como buscar enlaces "Siguiente" para paginación, etc., es mejor escribir su propio rastreador. Pero para el rastreo general, debe usar crawlspider y filtrar los enlaces que no necesita seguir usando las reglas & función process_links.

Eche un vistazo al código de crawlspider en \scrapy\contrib\spiders\crawl.py, no es demasiado complicado.

+0

en el acto! en realidad, olvidé mencionar que tengo la intención de seguir los enlaces "Siguiente". Gracias por la referencia. – romeroqj

Cuestiones relacionadas