with spider scraping example crawler python pandas beautifulsoup scrapy web-crawler

spider - selenium python



¿Problemas al intentar rastrear enlaces dentro de enlaces visitados con scrapy? (1)

Por lo que puedo ver, hay dos problemas con tu raspador:

  1. como se llama a cada elemento en start_urls y está creando y guardando un nuevo dataframe para cada enlace, los dataframes que está generando se sobrescriben entre sí.

Es por eso que siempre tendrá un solo resultado en su crawled_table.csv

Solución para esto: cree el marco de datos solo una vez y presione todos los elementos en el mismo objeto de marco de datos.

A continuación, guarde el marco de datos en cada llamada de parse , en caso de que el raspador se detenga antes de finalizar.

  1. if l == None: no funcionará como response.xpath devuelve una lista vacía si no se encontraron coincidencias. Así que if len(l) == 0: debería hacer

En una esencia, así es como estructuraría el raspador (¡código no probado!)

# -*- coding: utf-8 -*- class ToySpider(scrapy.Spider): name = "toy_example" allowed_domains = ["www.example.com"] start_urls = [''https:example1.com'', ''https:example2.com'', ''https:example3.com''] df = pd.DataFrame() def parse(self, response): links = response.xpath(".//*[@id=''object'']//tbody//tr//td//span//a[2]") items = [] if len(links) == 0: item = ToyItem() # build item with visited_link = NaN here item[''visited_link''] = response.url item[''extracted_link''] = ''NaN'' items.append(item) else: for l in links: item = ToyItem() # build the item as you previously did here item[''visited_link''] = response.url item[''extracted_link''] = l.xpath(''@href'').extract_first() items.append(item) items_df = pd.DataFrame(items) self.df = self.df.append(items_df, ignore_index=True) print(''/n/n/n/n/n'', self.df, ''/n/n/n/n/n'') self.df.to_csv(''/Users/user/Desktop/crawled_table.csv'', index=False) return items

Para aprender scrapy, estoy tratando de rastrear algunas URL internas de una lista de start_urls . El problema es que no todos los elementos de start_urls tienen urls internas (aquí me gustaría devolver NaN ). Por lo tanto, ¿cómo puedo devolver el siguiente 2 dataframe de columna (**) :

visited_link, extracted_link https://www.example1.com, NaN https://www.example2.com, NaN https://www.example3.com, https://www.extracted-link3.com

Hasta ahora, intenté:

En:

# -*- coding: utf-8 -*- class ToySpider(scrapy.Spider): name = "toy_example" allowed_domains = ["www.example.com"] start_urls = [''https:example1.com'', ''https:example2.com'', ''https:example3.com''] def parse(self, response): links = response.xpath(".//*[@id=''object'']//tbody//tr//td//span//a") lis_ = [] for l in links: item = ToyCrawlerItem() item[''visited_link''] = response.url item[''extracted_link''] = l.xpath(''@href'').extract_first() yield item lis_.append(item) df = pd.DataFrame(lis_) print(''/n/n/n/n/n'', df, ''/n/n/n/n/n'') df.to_csv(''/Users/user/Desktop/crawled_table.csv'', index=False)

Sin embargo, el código anterior me lo devuelve:

Fuera:

extracted_link,visited_link https://www.extracted-link.com,https://www.example1.com

Traté de gestionar los valores de emisión None con:

if l == None: item[''visited_link''] = ''NaN'' else: item[''visited_link''] = response.url

Pero no está funcionando, ninguna idea de cómo obtener (**)

* sí, un marco de datos, sé que puedo hacer -o , pero haré operaciones de dataframe.

ACTUALIZAR

Después de leer la respuesta de @rrschmidt intenté:

def parse(self, response): links = response.xpath(".//*[@id=''object'']//tbody//tr//td//span//a[2]") lis_ = [] for l in links: item = ToyItem() if len(l) == 0: item[''visited_link''] = ''NaN'' else: item[''visited_link''] = response.url #item[''visited_link''] = response.url item[''extracted_link''] = l.xpath(''@href'').extract_first() yield item print(''/n/n/n Aqui:/n/n'', item, "/n/n/n") lis_.append(item) df = pd.DataFrame(lis_) print(''/n/n/n/n/n'', df, ''/n/n/n/n/n'') df.to_csv(''/Users/user/Desktop/crawled_table.csv'', index=False)

Sin embargo, todavía me devolvió la misma salida incorrecta. ¿Alguien podría ayudarme a aclarar este problema?