Scrapy es un marco de rastreo web de código abierto escrito en Python que se utiliza para el raspado web, también se puede usar para extraer datos para fines generales. Primero, todos los enlaces de las subpáginas se toman de la página principal y luego la identificación del correo electrónico se extrae de estas subpáginas usando expresiones regulares.
Este artículo muestra la extracción de ID de correo electrónico del sitio geeksforgeeks como referencia.
ID de correo electrónico que se extraerán del sitio de geeksforgeeks: [‘feedback@geeksforgeeks.org’, ‘classes@geeksforgeeks.org’, ‘complaints@geeksforgeeks.org’, ‘review-team@geeksforgeeks.org’]
¿Cómo crear un proyecto de extracción de ID de correo electrónico usando Scrapy?
1. Instalación de paquetes : ejecute el siguiente comando desde la terminal
pip install scrapy pip install scrapy-selenium
2. Crear proyecto –
scrapy startproject projectname (Here projectname is geeksemailtrack) cd projectname scrapy genspider spidername (Here spidername is emails)
3) Agregue código en el archivo settings.py para usar scrapy-selenium
from shutil import which SELENIUM_DRIVER_NAME = 'chrome' SELENIUM_DRIVER_EXECUTABLE_PATH = which('chromedriver') SELENIUM_DRIVER_ARGUMENTS=[] DOWNLOADER_MIDDLEWARES = { 'scrapy_selenium.SeleniumMiddleware': 800 }
4) Ahora descargue el controlador de cromo para su cromo y colóquelo cerca de su archivo chrome scrapy.cfg. Para descargar el controlador de Chrome, consulte este sitio: para descargar el controlador de Chrome .
Estructura de directorios –
Código paso a paso –
1. Importe todas las bibliotecas necesarias:
Python3
# web scraping framework import scrapy # for regular expression import re # for selenium request from scrapy_selenium import SeleniumRequest # for link extraction from scrapy.linkextractors.lxmlhtml import LxmlLinkExtractor
2. Cree la función start_requests para visitar el sitio desde Selenium. Puede agregar su propia URL.
Python3
def start_requests(self): yield SeleniumRequest( url="https://www.geeksforgeeks.org/", wait_time=3, screenshot=True, callback=self.parse, dont_filter=True )
3. Crear función de análisis :
Python3
def parse(self, response): # this helps to get all links from source code links = LxmlLinkExtractor(allow=()).extract_links(response) # Finallinks contains links urk Finallinks = [str(link.url) for link in links] # links list for url that may have email ids links = [] # filtering and storing only needed url in links list # pages that are about us and contact us are the ones that have email ids for link in Finallinks: if ('Contact' in link or 'contact' in link or 'About' in link or 'about' in link or 'CONTACT' in link or 'ABOUT' in link): links.append(link) # current page url also added because few sites have email ids on there main page links.append(str(response.url)) # parse_link function is called for extracting email ids l = links[0] links.pop(0) # meta helps to transfer links list from parse to parse_link yield SeleniumRequest( url=l, wait_time=3, screenshot=True, callback=self.parse_link, dont_filter=True, meta={'links': links} )
Explicación de la función de análisis –
- En las siguientes líneas, todos los enlaces se extraen de https://www.geeksforgeeks.org/response.
links = LxmlLinkExtractor(allow=()).extract_links(response) Finallinks = [str(link.url) for link in links]
- Finallinks es una lista que contiene todos los enlaces.
- Para evitar enlaces innecesarios, colocamos un filtro que, si los enlaces pertenecen al contacto y a la página, solo extraemos los detalles de esa página.
for link in Finallinks: if ('Contact' in link or 'contact' in link or 'About' in link or 'about' in link or or 'CONTACT' in link or 'ABOUT' in link): links.append(link)
- Este filtro anterior no es necesario, pero los sitios tienen muchas etiquetas (enlaces) y, debido a esto, si el sitio tiene 50 subpáginas en el sitio, extraerá el correo electrónico de estas 50 sub URL. se supone que los correos electrónicos se encuentran principalmente en la página de inicio, la página de contacto y la página de información, por lo que este filtro ayuda a reducir la pérdida de tiempo al eliminar esas URL que pueden no tener identificaciones de correo electrónico.
- Los enlaces de las páginas que pueden tener identificadores de correo electrónico se solicitan uno por uno y los identificadores de correo electrónico se extraen utilizando expresiones regulares.
4. Cree el código de función parse_link :
Python3
def parse_link(self, response): # response.meta['links'] this helps to get links list links = response.meta['links'] flag = 0 # links that contains following bad words are discarded bad_words = ['facebook', 'instagram', 'youtube', 'twitter', 'wiki', 'linkedin'] for word in bad_words: # if any bad word is found in the current page url # flag is assigned to 1 if word in str(response.url): flag = 1 break # if flag is 1 then no need to get email from # that url/page if (flag != 1): html_text = str(response.text) # regular expression used for email id email_list = re.findall('\w+@\w+\.{1}\w+', html_text) # set of email_list to get unique email_list = set(email_list) if (len(email_list) != 0): for i in email_list: # adding email ids to final uniqueemail self.uniqueemail.add(i) # parse_link function is called till # if condition satisfy # else move to parsed function if (len(links) > 0): l = links[0] links.pop(0) yield SeleniumRequest( url=l, callback=self.parse_link, dont_filter=True, meta={'links': links} ) else: yield SeleniumRequest( url=response.url, callback=self.parsed, dont_filter=True )
Explicación de la función parse_link:
Mediante response.text obtenemos todo el código fuente de la URL solicitada. La expresión regular ‘\w+@\w+\.{1}\w+’ que se usa aquí podría traducirse a algo como esto Busque cada fragmento de string que comience con una o más letras, seguidas de un signo de arroba (‘@’) , seguido de una o más letras con un punto al final.
Después de eso, debería volver a tener una o más letras. Es una expresión regular utilizada para obtener la identificación del correo electrónico.
5. Crear función analizada –
Python3
def parsed(self, response): # emails list of uniqueemail set emails = list(self.uniqueemail) finalemail = [] for email in emails: # avoid garbage value by using '.in' and '.com' # and append email ids to finalemail if ('.in' in email or '.com' in email or 'info' in email or 'org' in email): finalemail.append(email) # final unique email ids from geeksforgeeks site print('\n'*2) print("Emails scraped", finalemail) print('\n'*2)
Explicación de la función analizada:
la expresión regular anterior también conduce a valores basura como select@1.13 en esta identificación de correo electrónico de geeksforgeeks, sabemos que select@1.13 no es una identificación de correo electrónico. El filtro de función analizada aplica un filtro que solo acepta correos electrónicos que contienen ‘.com’ y “.in”.
Ejecute la araña usando el siguiente comando:
scrapy crawl spidername (spidername is name of spider)
Valor basura en correos electrónicos raspados:
Correos electrónicos raspados finales:
Python
# web scraping framework import scrapy # for regular expression import re # for selenium request from scrapy_selenium import SeleniumRequest # for link extraction from scrapy.linkextractors.lxmlhtml import LxmlLinkExtractor class EmailtrackSpider(scrapy.Spider): # name of spider name = 'emailtrack' # to have unique email ids uniqueemail = set() # start_requests sends request to given https://www.geeksforgeeks.org/ # and parse function is called def start_requests(self): yield SeleniumRequest( url="https://www.geeksforgeeks.org/", wait_time=3, screenshot=True, callback=self.parse, dont_filter=True ) def parse(self, response): # this helps to get all links from source code links = LxmlLinkExtractor(allow=()).extract_links(response) # Finallinks contains links urk Finallinks = [str(link.url) for link in links] # links list for url that may have email ids links = [] # filtering and storing only needed url in links list # pages that are about us and contact us are the ones that have email ids for link in Finallinks: if ('Contact' in link or 'contact' in link or 'About' in link or 'about' in link or 'CONTACT' in link or 'ABOUT' in link): links.append(link) # current page url also added because few sites have email ids on there main page links.append(str(response.url)) # parse_link function is called for extracting email ids l = links[0] links.pop(0) # meta helps to transfer links list from parse to parse_link yield SeleniumRequest( url=l, wait_time=3, screenshot=True, callback=self.parse_link, dont_filter=True, meta={'links': links} ) def parse_link(self, response): # response.meta['links'] this helps to get links list links = response.meta['links'] flag = 0 # links that contains following bad words are discarded bad_words = ['facebook', 'instagram', 'youtube', 'twitter', 'wiki', 'linkedin'] for word in bad_words: # if any bad word is found in the current page url # flag is assigned to 1 if word in str(response.url): flag = 1 break # if flag is 1 then no need to get email from # that url/page if (flag != 1): html_text = str(response.text) # regular expression used for email id email_list = re.findall('\w+@\w+\.{1}\w+', html_text) # set of email_list to get unique email_list = set(email_list) if (len(email_list) != 0): for i in email_list: # adding email ids to final uniqueemail self.uniqueemail.add(i) # parse_link function is called till # if condition satisfy # else move to parsed function if (len(links) > 0): l = links[0] links.pop(0) yield SeleniumRequest( url=l, callback=self.parse_link, dont_filter=True, meta={'links': links} ) else: yield SeleniumRequest( url=response.url, callback=self.parsed, dont_filter=True ) def parsed(self, response): # emails list of uniqueemail set emails = list(self.uniqueemail) finalemail = [] for email in emails: # avoid garbage value by using '.in' and '.com' # and append email ids to finalemail if ('.in' in email or '.com' in email or 'info' in email or 'org' in email): finalemail.append(email) # final unique email ids from geeksforgeeks site print('\n'*2) print("Emails scraped", finalemail) print('\n'*2)
Video de trabajo del código anterior –
Referencia – extractores de enlaces