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:
- 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.
-
if l == None:
no funcionará comoresponse.xpath
devuelve una lista vacía si no se encontraron coincidencias. Así queif 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?