En este ejemplo, he recuperado la URL «https://www.urbandictionary.com/define.php?term=YOLO» y he guardado el código HTML en el archivo test_output.html.
(scrapy_env) mihai@DESKTOP-0RN92KH:~/myproject$ scrapy shell --nolog
[s] Available Scrapy objects:
[s] scrapy scrapy module (contains scrapy.Request, scrapy.Selector, etc)
[s] crawler <scrapy.crawler.Crawler object at 0x7f1eef80f6a0>
[s] item {}
[s] settings <scrapy.settings.Settings object at 0x7f1eef80f4c0>
[s] Useful shortcuts:
[s] fetch(url[, redirect=True]) Fetch URL and update local objects (by default, redirects are followed)
[s] fetch(req) Fetch a scrapy.Request and update local objects
[s] shelp() Shell help (print this help)
[s] view(response) View response in a browser
>>> response // response is empty
>>> fetch('https://www.urbandictionary.com/define.php?term=YOLO')
>>> response
<200 https://www.urbandictionary.com/define.php?term=Yolo>
>>> with open('test_output.html', 'w') as f:
... f.write(response.text)
...
118260
Ahora vamos a examinar test_output.html e identificar los selectores que necesitaríamos para extraer los datos para nuestro rastreador de Urban Dictionary.
Podemos observar que:
- Cada contenedor de definición de palabra tiene la clase «definition».
- El significado de la palabra se encuentra dentro del div con la clase «meaning».
- Los ejemplos de la palabra se encuentran dentro del div con la clase «example».
- La información sobre el autor y la fecha de la publicación se encuentra dentro del div con la clase «contributor».
Ahora probemos algunos selectores en el Scrapy Shell:
Para obtener referencias a todos los contenedores de definiciones, podemos utilizar selectores CSS o XPath:
Puedes obtener más información sobre los selectores XPath aquí: https://www.webscrapingapi.com/the-ultimate-xpath-cheat-sheet
definitions = response.css('div.definition')
definitions = response.xpath('//div[contains(@class,"definition")]')
Debemos extraer el significado, el ejemplo y la información de la publicación de cada contenedor de definición. Probemos algunos selectores con el primer contenedor:
>>> first_def = definitions[0]
>>> meaning = first_def.css('div.meaning').xpath(".//text()").extract()
>>> meaning
['Yolo ', 'means', ', '', 'You Only Live Once', ''.']
>>> meaning = "".join(meaning)
>>> meaning
'Yolo means, 'You Only Live Once'.'
>>> example = first_def.css('div.example').xpath(".//text()").extract()
>>> example = "".join(example)
>>> example
'"Put your seatbelt on." Jessica said.\r"HAH, YOLO!" Replies Anna.\r(They then proceed to have a car crash. Long story short...Wear a seatbelt.)'
>>> post_data = first_def.css('div.contributor').xpath(".//text()").extract()
>>> post_data
['by ', 'Soy ugly', ' April 24, 2019']
Al utilizar el Scrapy Shell, hemos podido encontrar rápidamente un selector general que se adapta a nuestras necesidades.
definition.css('div.<meaning|example|contributor>').xpath(".//text()").extract()
// returns an array with all the text found inside the <meaning|example|contributor>
ex: ['Yolo ', 'means', ', '', 'You Only Live Once', ''.']
Para obtener más información sobre los selectores de Scrapy, consulta la documentación. https://docs.scrapy.org/en/latest/topics/selectors.html