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:
- raspe la página siguiente para artículos específicos (y eventualmente los devuelva)
- 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!