urljoin follow example python scrapy

python - follow - scrapy-análisis de elementos que están paginados



scrapy python documentation (3)

Puede haber dos casos de uso para ''elementos de análisis desechados que están paginados''.

UNA). Solo queremos desplazarnos por la tabla y buscar datos. Esto es relativamente sencillo.

class TrainSpider(scrapy.Spider): name = "trip" start_urls = [''somewebsite''] def parse(self, response): '''''' do something with this parser '''''' next_page = response.xpath("//a[@class=''next_page'']/@href").extract_first() if next_page is not None: next_page = response.urljoin(next_page) yield scrapy.Request(next_page, callback=self.parse)

Observa las últimas 4 líneas. aquí

  1. Obtenemos el formulario de enlace de la siguiente página xpath de la página siguiente desde el botón de paginación "Siguiente".
  2. Si es condición para comprobar si no es el final de la paginación.
  3. Únase a este enlace (que obtuvimos en el paso 1) con la url principal usando url join
  4. Una llamada recursiva al método parse call back.

B) No solo queremos movernos a través de las páginas, sino que también queremos extraer datos de uno o más enlaces en esa página.

class StationDetailSpider(CrawlSpider): name = ''train'' start_urls = [someOtherWebsite] rules = ( Rule(LinkExtractor(restrict_xpaths="//a[@class=''next_page'']"), follow=True), Rule(LinkExtractor(allow=r"/trains//d+$"), callback=''parse_trains'') ) def parse_trains(self, response): ''''''do your parsing here''''''

En cualquier lugar, observe que:

  1. Estamos utilizando la subclase CrawlSpider de la clase principal scrapy.Spider

  2. Nos hemos puesto a ''Reglas''

    a) La primera regla, solo verifica si hay una ''próxima_página'' disponible y la sigue.

    b) La segunda regla solicita todos los enlaces en una página que están en el formato, digamos /trains/12343 y luego llama a parse_trains para realizar y analizar la operación.

  3. Importante : tenga en cuenta que no queremos utilizar el método de parse regular aquí, ya que estamos utilizando la subclase CrawlSpider . Esta clase también tiene un método de parse por lo que no queremos anularlo. Solo recuerde nombrar su método de devolución de llamada de otra manera que no sea parse .

Tengo un url de la forma:

example.com/foo/bar/page_1.html

Hay un total de 53 páginas, cada una de ellas tiene ~ 20 filas.

Básicamente quiero obtener todas las filas de todas las páginas, es decir, ~ 53 * 20 elementos.

Tengo un código de trabajo en mi método de análisis, que analiza una sola página, y también va una página más por artículo, para obtener más información sobre el artículo:

def parse(self, response): hxs = HtmlXPathSelector(response) restaurants = hxs.select(''//*[@id="contenido-resbus"]/table/tr[position()>1]'') for rest in restaurants: item = DegustaItem() item[''name''] = rest.select(''td[2]/a/b/text()'').extract()[0] # some items don''t have category associated with them try: item[''category''] = rest.select(''td[3]/a/text()'').extract()[0] except: item[''category''] = '''' item[''urbanization''] = rest.select(''td[4]/a/text()'').extract()[0] # get profile url rel_url = rest.select(''td[2]/a/@href'').extract()[0] # join with base url since profile url is relative base_url = get_base_url(response) follow = urljoin_rfc(base_url,rel_url) request = Request(follow, callback = parse_profile) request.meta[''item''] = item return request def parse_profile(self, response): item = response.meta[''item''] # item[''address''] = figure out xpath return item

La pregunta es, ¿cómo rastro cada página?

example.com/foo/bar/page_1.html example.com/foo/bar/page_2.html example.com/foo/bar/page_3.html ... ... ... example.com/foo/bar/page_53.html


Puede usar CrawlSpider en lugar de BaseSpider y usar SgmlLinkExtractor para extraer las páginas de la paginación.

Por ejemplo:

start_urls = ["www.example.com/page1"] rules = ( Rule (SgmlLinkExtractor(restrict_xpaths=(''//a[@class="next_page"]'',)) , follow= True), Rule (SgmlLinkExtractor(restrict_xpaths=(''//div[@class="foto_imovel"]'',)) , callback=''parse_call'') )

La primera regla le dice a scrapy que siga el enlace contenido en la expresión xpath, la segunda regla le dice a scrapy que llame a parse_call a los enlaces contenidos en la expresión xpath, en caso de que quiera analizar algo en cada página.

Para obtener más información, consulte el doc: http://doc.scrapy.org/en/latest/topics/spiders.html#crawlspider


Tienes dos opciones para resolver tu problema. El general es usar el yield para generar nuevas solicitudes en lugar de return . De esa manera, puede emitir más de una nueva solicitud desde una sola devolución de llamada. Consulte el segundo ejemplo en http://doc.scrapy.org/en/latest/topics/spiders.html#basespider-example .

En su caso, probablemente haya una solución más simple: simplemente genere la lista de urs de inicio a partir de un patrón como este:

class MySpider(BaseSpider): start_urls = [''http://example.com/foo/bar/page_%s.html'' % page for page in xrange(1,54)]