Cómo construir un bot de web scraping en Python

En este artículo, vamos a ver cómo construir un bot de web scraping en Python.

Web Scraping es un proceso de extracción de datos de sitios web. Un Bot es una pieza de código que automatizará nuestra tarea. Por lo tanto, un bot de raspado web es un programa que raspará automáticamente un sitio web en busca de datos, según nuestros requisitos.    

Módulo necesario

  • bs4 : Beautiful Soup (bs4) es una biblioteca de Python para extraer datos de archivos HTML y XML. Este módulo no viene integrado con Python. Para instalar este tipo, escriba el siguiente comando en la terminal.

pip instalar bs4

  • requests : Request le permite enviar requests HTTP/1.1 de manera extremadamente fácil. Este módulo tampoco viene integrado con Python. Para instalar este tipo, escriba el siguiente comando en la terminal.

requests de instalación de pip

  • Selenium : Selenium es una de las herramientas de prueba de automatización más populares. Se puede utilizar para automatizar navegadores como Chrome, Firefox, Safari, etc.

pip instalar selenium

Método 1: usar selenium

Necesitamos instalar un controlador de cromo para automatizar el uso de selenium, nuestra tarea es crear un bot que rastreará continuamente el sitio web de noticias de Google y mostrará todos los titulares cada 10 minutos.

Implementación paso a paso :

Paso 1: Primero importaremos algunos módulos requeridos.

Python3

# These are the imports to be made
import time
from selenium import webdriver
from datetime import datetime

Paso 2: El siguiente paso es abrir el sitio web requerido.

Python3

# path of the chromedriver we have just downloaded
PATH = r"D:\chromedriver"
driver = webdriver.Chrome(PATH)  # to open the browser
  
# url of google news website
url = 'https://news.google.com/topstories?hl=en-IN&gl=IN&ceid=IN:en'
  
# to open the url in the browser
driver.get(url)  

Producción:

Paso 3: Extraer el título de la noticia de la página web, para extraer una parte específica de la página, necesitamos su XPath, al que se puede acceder haciendo clic derecho en el elemento requerido y seleccionando Inspeccionar en la barra desplegable. 

Después de hacer clic en Inspeccionar, aparece una ventana. A partir de ahí, tenemos que copiar el XPath completo de los elementos para acceder a él:

Nota: es posible que no siempre obtenga el elemento exacto que desea al inspeccionar (depende de la estructura del sitio web), por lo que es posible que deba navegar por el código HTML durante un tiempo para obtener el elemento exacto que desea. Y ahora, simplemente copie esa ruta y péguela en su código. Después de ejecutar todas estas líneas de código, obtendrá el título del primer encabezado impreso en su terminal.

Python3

# Xpath you just copied
news_path = '/html/body/c-wiz/div/div[2]/div[2]/\
div/main/c-wiz/div[1]/div[3]/div/div/article/h3/a'
  
# to get that element
link = driver.find_element_by_xpath(news_path)  
  
# to read the text from that element
print(link.text)  

Producción:

‘Ataque en territorio afgano’: Talibán en ataque aéreo estadounidense que mató a 2 hombres de ISIS-K

Paso 4: Ahora, el objetivo es obtener los X_Paths de todos los titulares presentes. 

Una forma es que podemos copiar todos los XPaths de todos los titulares (alrededor de 6 titulares estarán allí en las noticias de Google cada vez) y podemos obtenerlos todos, pero ese método no es adecuado si hay una gran cantidad de cosas para ser desechado Entonces, la forma elegante es encontrar el patrón de los XPaths de los títulos que harán que nuestras tareas sean mucho más fáciles y eficientes. A continuación se muestran los XPaths de todos los titulares del sitio web y averigüemos el patrón.

/html/body/c-wiz/div/div[2]/div[2]/div/main/c-wiz/div[1]/div[ 3 ]/div/div/article/h3/a

/html/body/c-wiz/div/div[2]/div[2]/div/main/c-wiz/div[1]/div[ 4 ]/div/div/article/h3/a

/html/body/c-wiz/div/div[2]/div[2]/div/main/c-wiz/div[1]/div[ 5 ]/div/div/article/h3/a

/html/body/c-wiz/div/div[2]/div[2]/div/main/c-wiz/div[1]/div[ 6 ]/div/div/article/h3/a

/html/body/c-wiz/div/div[2]/div[2]/div/main/c-wiz/div[1]/div[ 7 ]/div/div/article/h3/a

/html/body/c-wiz/div/div[2]/div[2]/div/main/c-wiz/div[1]/div[ 8 ]/div/div/article/h3/a

Entonces, al ver estos XPath, podemos ver que solo el 5to div está cambiando (los que están en negrita). Entonces, en base a esto, podemos generar los XPaths de todos los titulares. Obtendremos todos los títulos de la página accediendo a ellos con su XPath. Entonces, para extraer todo esto, tenemos el código como 

Python3

# I have used f-strings to format the string
c = 1
for x in range(3, 9):
    print(f"Heading {c}: ")
    c += 1
    curr_path = f'/html/body/c-wiz/div/div[2]/div[2]/div/main\
    /c-wiz/div[1]/div[{x}]/div/div/article/h3/a'
    title = driver.find_element_by_xpath(curr_path)
    print(title.text)

Producción:

Ahora, el código está casi completo, lo último que tenemos que hacer es que el código obtenga titulares cada 10 minutos. Así que ejecutaremos un bucle while y dormiremos durante 10 minutos después de recibir todos los titulares.

A continuación se muestra la implementación completa.

Python3

import time
from selenium import webdriver
from datetime import datetime
  
PATH = r"D:\chromedriver"
  
driver = webdriver.Chrome(PATH)
  
url = 'https://news.google.com/topstories?hl=en-IN&gl=IN&ceid=IN:en'
  
driver.get(url)
  
while(True):
    now = datetime.now()
      
    # this is just to get the time at the time of 
    # web scraping
    current_time = now.strftime("%H:%M:%S")
    print(f'At time : {current_time} IST')
    c = 1
  
    for x in range(3, 9):
        curr_path = ''
          
        # Exception handling to handle unexpected changes
        # in the structure of the website
        try:
            curr_path = f'/html/body/c-wiz/div/div[2]/div[2]/\
            div/main/c-wiz/div[1]/div[{x}]/div/div/article/h3/a'
            title = driver.find_element_by_xpath(curr_path)
        except:
            continue
        print(f"Heading {c}: ")
        c += 1
        print(title.text)
          
    # to stop the running of code for 10 mins
    time.sleep(600) 

Producción:

Método 2: Uso de requests y BeautifulSoup

El módulo de requests obtiene los datos HTML sin procesar de los sitios web y se usa una sopa hermosa para analizar esa información claramente para obtener los datos exactos que necesitamos. A diferencia de Selenium, no requiere la instalación de un navegador y es aún más ligero porque accede directamente a la web sin la ayuda de un navegador.

Implementación paso a paso:

Paso 1: módulo de importación.

Python3

import requests
from bs4 import BeautifulSoup
import time

Paso 2: Lo siguiente que debe hacer es obtener los datos de la URL y luego analizar el código HTML

Python3

url = 'https://finance.yahoo.com/cryptocurrencies/'
response = requests.get(url)
text = response.text
data = BeautifulSoup(text, 'html.parser')

Paso 3: Primero, obtendremos todos los encabezados de la tabla.

Python3

# since, headings are the first row of the table
headings = data.find_all('tr')[0]
headings_list = []  # list to store all headings
  
for x in headings:
    headings_list.append(x.text)
# since, we require only the first ten columns
headings_list = headings_list[:10]
  
print('Headings are: ')
for column in headings_list:
    print(column)

Producción:

Paso 4: De la misma forma se pueden obtener todos los valores de cada fila

Python3

# since we need only first five coins
for x in range(1, 6):
    table = data.find_all('tr')[x]
    c = table.find_all('td')
      
    for x in c:
        print(x.text, end=' ')
    print('')

Producción:

A continuación se muestra la implementación completa:

Python3

import requests
from bs4 import BeautifulSoup
from datetime import datetime
import time
  
while(True):
    now = datetime.now()
      
    # this is just to get the time at the time of
    # web scraping
    current_time = now.strftime("%H:%M:%S")
    print(f'At time : {current_time} IST')
  
    response = requests.get('https://finance.yahoo.com/cryptocurrencies/')
    text = response.text
    html_data = BeautifulSoup(text, 'html.parser')
    headings = html_data.find_all('tr')[0]
    headings_list = []
    for x in headings:
        headings_list.append(x.text)
    headings_list = headings_list[:10]
  
    data = []
  
    for x in range(1, 6):
        row = html_data.find_all('tr')[x]
        column_value = row.find_all('td')
        dict = {}
          
        for i in range(10):
            dict[headings_list[i]] = column_value[i].text
        data.append(dict)
          
    for coin in data:
        print(coin)
        print('')
    time.sleep(600)

Producción:

Alojar el bot

Este es un método específico, utilizado para ejecutar el bot continuamente en línea sin necesidad de intervención humana. replit.com es un compilador en línea, donde ejecutaremos el código. Crearemos un mini servidor web con la ayuda de un módulo de matraz en python que ayuda en la ejecución continua del código. Cree una cuenta en ese sitio web y cree una nueva respuesta.

Después de crear la respuesta, cree dos archivos, uno para ejecutar el código del bot y el otro para crear el servidor web usando el matraz.

Código para cryptotracker.py:

Python3

import requests
from bs4 import BeautifulSoup
from datetime import datetime
import time
  
# keep_alive function, that maintains continuous 
# running of the code.
from keep_alive import keep_alive
import pytz
  
# to start the thread
keep_alive()
while(True):
    tz_NY = pytz.timezone('Asia/Kolkata')
    datetime_NY = datetime.now(tz_NY)
      
    # this is just to get the time at the time of web scraping
    current_time = datetime_NY.strftime("%H:%M:%S - (%d/%m)")
    print(f'At time : {current_time} IST')
  
    response = requests.get('https://finance.yahoo.com/cryptocurrencies/')
    text = response.text
    html_data = BeautifulSoup(text, 'html.parser')
  
    headings = html_data.find_all('tr')[0]
    headings_list = []
    for x in headings:
        headings_list.append(x.text)
    headings_list = headings_list[:10]
  
    data = []
  
    for x in range(1, 6):
        row = html_data.find_all('tr')[x]
        column_value = row.find_all('td')
        dict = {}
        for i in range(10):
            dict[headings_list[i]] = column_value[i].text
        data.append(dict)
  
    for coin in data:
        print(coin)
  
    time.sleep(60)

Código para el keep_alive.py (servidor web):

Python3

from flask import Flask
from threading import Thread
  
app = Flask('')
  
@app.route('/')
def home():
    return "Hello. the bot is alive!"
  
def run():
  app.run(host='0.0.0.0',port=8080)
  
def keep_alive():
    t = Thread(target=run)
    t.start()

Keep-alive es un método en redes que se utiliza para evitar que se rompa un determinado enlace. Aquí, el propósito del código de mantenimiento es crear un servidor web usando un matraz, que mantendrá activo el hilo del código (código de seguimiento criptográfico) para que pueda brindar actualizaciones continuamente.

Ahora, tenemos un servidor web creado, y ahora, necesitamos algo para hacer ping continuamente para que el servidor no se caiga y el código siga ejecutándose continuamente. Hay un sitio web uptimerobot.com que hace este trabajo. Crea una cuenta en ella 

Ejecutando el código de seguimiento de Crypto en Replit. Por lo tanto, hemos creado con éxito un bot de raspado web que desechará el sitio web en particular continuamente cada 10 minutos e imprimirá los datos en la terminal.

Publicación traducida automáticamente

Artículo escrito por tanuj_tvs y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *