tutorial scrap pages follow crawling crawler python callback scrapy

python - pages - scrapy to mongodb



Rendimiento de ambos artículos y solicitud de devolución de llamada en scrapy (1)

Hay 2 niveles de tu problema.

1. Bio url no está disponible con JS deshabilitado. Desactive JS en su navegador y consulte esta página: https://votesmart.org/candidate/126288/derek-stanford

Debería ver la etiqueta con href vacío y la URL correcta oculta en el comentario.

<a href="#" class="folder" id="folder-bio"> <!--<a href=''/candidate/biography/126288/derek-stanford'' itemprop="url" class=''more''> See Full Biographical and Contact Information</a>-->

Para extraer bio url, puede obtener este comentario con el selector xpath "/ comment ()", y luego extraer url con regexp.

O bien, si la estructura de la url es común para todas las páginas, simplemente formule la url usted mismo: reemplace "/ candidate /" en el enlace con "/ candidate / biography /".

¡NÓTESE BIEN! Si se enfrenta a problemas inesperados, una de las primeras acciones: deshabilite JS y mire la página como la verá Scrapy. Pruebe todos los selectores

2. Su uso de los artículos es muy complicado. Si "un elemento = una persona", solo debe definir un elemento en "parse_person" y pasarlo a "parse_bio".

Eche un vistazo al código actualizado. Reescribí algunas partes mientras encontraba el problema. Notas:

  • No es necesario (en la mayoría de los casos) crear una lista de "elementos" y anexarle elementos. Scrapy administra con los artículos en sí.
  • "sel = Selector (respuesta)" no tiene sentido en tu código, puedes lanzarlo.

Este código se prueba con Scrapy 1.0 y Python 3.5, aunque con versiones anteriores debería funcionar también.

from scrapy import Spider, Request class VSSpider(Spider): name = "vs5" allowed_domains = ["votesmart.org"] start_urls = ["https://votesmart.org/officials/WA/L/washington-state-legislative"] def parse(self, response): for href in response.css(''h5 a::attr(href)'').extract(): person_url = response.urljoin(href) yield Request(person_url, callback=self.parse_person) def parse_person(self, response): # former "parse1" # define item, one for both parse_person and bio function item = LegislatorsItems() # extract text from left menu table and populate to item desc_rows = response.css(''.span-abbreviated td::text'').extract() if desc_rows: item[''current_office''] = desc_rows[0] item[''running_for''] = desc_rows[1] if len(desc_rows) > 1 else None # create right bio url and pass item to it bio_url = response.url.replace(''votesmart.org/candidate/'', ''votesmart.org/candidate/biography/'') return Request(bio_url, callback=self.parse_bio, meta={''item'': item}) def parse_bio(self, response): # former "parse2" # get item from meta, add "tester" data and return item = response.meta[''item''] item[''tester''] = response.css(''.item.first'').xpath(''//li[3]'').extract() print(item) # for python 2: print item return item

Descargo de responsabilidad: soy bastante nuevo para Python y Scrapy.

Intento que mi araña junte las URL desde la url de inicio, siga esas URL reunidas y ambas:

  1. raspe la página siguiente para artículos específicos (y eventualmente los devuelva)
  2. reúna URL más específicas de la página siguiente y siga estas direcciones URL.

Quiero poder continuar este proceso de entrega de elementos y solicitudes de devolución de llamada, pero no estoy muy seguro de cómo hacerlo. Actualmente mi código solo devuelve urls y no elementos. Obviamente estoy haciendo algo mal. Cualquier comentario sería muy apreciado.

class VSSpider(scrapy.Spider): name = "vs5" allowed_domains = ["votesmart.org"] start_urls = [ "https://votesmart.org/officials/WA/L/washington-state-legislative#.V8M4p5MrKRv", ] def parse(self, response): sel = Selector(response) #this gathers links to the individual legislator pages, it works for href in response.xpath(''//h5/a/@href''): url = response.urljoin(href.extract()) yield scrapy.Request(url, callback=self.parse1) def parse1(self, response): sel = Selector(response) items = [] #these xpaths are on the next page that the spider should follow, when it first visits an individual legislator page for sel in response.xpath(''//*[@id="main"]/section/div/div/div''): item = LegislatorsItems() item[''current_office''] = sel.xpath(''//tr[1]/td/text()'').extract() item[''running_for''] = sel.xpath(''//tr[2]/td/text()'').extract() items.append(item) #this is the xpath to the biography of the legislator, which it should follow and scrape next for href in response.xpath(''//*[@id="folder-bio"]/@href''): url = response.urljoin(href.extract()) yield scrapy.Request(url, callback=self.parse2, meta={''items'': items}) def parse2(self, response): sel = Selector(response) items = response.meta[''items''] #this is an xpath on the biography page for sel in response.xpath(''//*[@id="main"]/section/div[2]/div/div[3]/div/''): item = LegislatorsItems() item[''tester''] = sel.xpath(''//div[2]/div[2]/ul/li[3]'').extract() items.append(item) return items

¡Gracias!