Skip to content

Latest commit

 

History

History
477 lines (379 loc) · 16.6 KB

README.md

File metadata and controls

477 lines (379 loc) · 16.6 KB

🤖 Creando BOTS de Twitter con Python y Web Scraping


📅 Impartido 3, 4 y 5 de Octubre, 2022

⏰ Seis horas teórico-prácticas

💻Congreso de Ciencias Básicas

🏫 Universidad Autónoma de Aguascalientes

🌮 En Español


📋 Requisitos

🛠 Instalaciones:

🐦 Cuentas:


🗂 Índice



1️⃣ Primer día

📚 Tópicos

  1. Teoría sobre internet, bots, scraping y APIS.
  2. Primer loggeo en la plataforma de desarrollador de Twitter.
  3. Definición y partes de un HTTP Request.
  4. Ejercicio sobre APIS:
    • Extraer y abrir fotos aleatorias de gatos.
    • Traer datos interesantes sobre Pokémons.
    • Traer canciones más populares de una banda, con Spotify.
    • Ejercicio con API de Marvel.

📓 Apuntes


🔰 Librería en Python para hacer peticiones http:

Instalación en consola:

python -m pip install requests

O bien:

pip install requests

Importación en código:

import requests

🔰 Ejemplo de uso para hacer petición GET:

# Se guarda en "respuesta", el resultado de hacer la petición GET:
respuesta = requests.get("https://api.thecatapi.com/v1/images/search")
print(respuesta) # ---> Imprime algo como <Response[200]>;

# Para obtener los meta-datos que trae la petición:
estatus = respuesta.status_code
cabezera = respuesta.headers
contenido = respuesta.content
texto = respuesta.text
contenidox = respuesta._content
encoding = respuesta.encoding

# Se convierte la respuesta a un archivo JSON para procesarlo:
respuestaEnJSON = respuesta.json()
print(respuestaEnJSON) # ---> Imprime el JSON de la respuesta>;

# SI QUERÉMOS SÓLO EL CONTENIDO DE LA RESPUESTA:
contenidoRespuesta = respuesta.content

# SI EL CONTENIDO DE LA RESPUESTA ES CÓDIGO HTML;
# ES NECESARIO DECODIFICARLO PARA EVITAR ERRORES CON CARACTERES ESPECIALES:
contenidoRespuesta = respuesta.content.decode("utf-8")

📖 Para entender cómo leer y procesar JSONs:

🧰 Recursos:



2️⃣ Segundo día

📚 Tópicos

  1. ¿Qué es el scraping?
  2. ¿Qué es xPath?
  3. Implementando xPath en el navegador:
    • Extraer frases celebres.
    • Extraer información sobre libros.
  4. Ejercicios en Python:
    • Obtener letra de una canción dicha por el usuario.
    • Obtener descuentos en juegos populares de Steam.

📓 Apuntes


🔰 xPath:

⭕ Revisar carpeta de apuntes;

🔰 xPath en Python:

Instalar librería

python -m pip install lxml

O bien:

pip install lxml

Importación en código:

import lxml.html as html

❗ NOTA: También necesitarémos la librería antes mencionada requests.

🔰 Ejemplo de uso de hacer scraping:

# Hacer request para la página que se desea scrapear:
respuesta = requests.get(urlDeLaWeb)

# Obtener el content del response (Que en este caso
# es un HTML, en lugar de un JSON, como antes). Este
# se debe decodificar con "utf-8" para evitar errores
# en el formato de caractéres especiales:
htmlDeLaWeb = respuesta.content.decode("utf-8")

# Se utiliza la librería que importamos con el nombre
# de "html" para convertir el HTML a un objeto que
# podrá procesar la librería con xPath:
htmlParaScrapear = html.fromstring(htmlDeLaWeb)

# Hacemos scraping a la página y guardamos el resultado:
consultaXPATH = '//a[@class="song"]/text()'
resultadoDelScraping = htmlParaScrapear.xpath(consultaXPATH)

🔰 Funciones útiles de Python para procesar texto:

  • Eliminar los espacios de un texto al principio y al final:
nombreCancion = nombreCancion.strip()
  • Eliminar los espacios duplicados en un texto:
nombreCancion = " ".join(nombreCancion.split())
  • Reemplazar los espacios de un texto por "%20"...
nombreCancion = nombreCancion.replace(" ", "%20")

📖 Para entender cómo recorrer listas con Python:

🧰 Recursos:



3️⃣ Tercer día

📚 Tópicos

  1. Explorar funciones básicas de la API de Tweeter.
  2. Ejercicios básicos con Twitter:
    • Twittear.
    • Retwitear.
    • Responder menciones.
    • Enviar DMs.
    • Seguir hastags.
  3. Programación del proyecto:
    • Identificar web de Steam.
    • Encontrar xPath para traer datos.
    • Hacer scraping en consola.
    • Colocar resultados en Twits.

📓 Apuntes


🔰 Crear un entorno virtual en Python:

Comando para crearlo:

python -m venv venv

❗ NOTA: PARA CREAR EL ENTORNO VIRTUAL EN CONSOLA NO OLVIDES CAMBIAR DE DIRECTORIO A DONDE VA A ESTAR EL PROYECTO. Para moverte de directorio en consola, ejecuta el comando cd nombredelacarpeta.

✔ En Windows:

Para activarlo:

.\venv\Scripts\activate

Para desactivarlo:

.\venv\Scripts\deactivate.bat

✔ En MAC:

Para activarlo:

source venv\Scripts\activate

Para desactivarlo:

source venv\Scripts\deactivate.bat

🔰 Cómo esconder varibables secretas:

1. Primero instala la librería python-dotenv:

python -m pip install python-dotenv

O bien...

pip install python-dotenv

2. Crea dentro de la carpeta de tu proyecto un archivo de nombre .env.

3. En .env vas a colocar las variables que quieres esconder, junto a su valor, y separadas por un signo "=", y una en cada línea. Es recomendable como estándar, colocar el nombre de las variables en letras mayúsculas. Además, no escribas espacios. (EJEMPLO):

API_KEY=xxxxxxxxxxxxxxxxxxxx
API_SECRET=0000000000000000000000
TOKEN=000000.xxxxxxxx.0000.XXXXXXX.00

4. Dentro del código en el que quieres acceder a las variables:

# Importa la función de la librería...
from dotenv import load_dotenv
import os

# Cargar las varibales de entorno con la función...
load_dotenv()

# Obten las variables según el nombre que les pusiste...
llaveDeLaAPI = os.getenv("API_KEY")
secretoDeLaAPI = os.getenv("API_SECRET")
tokenDeLaAPI = os.getenv("TOKEN")

❌ NO OLVIDES EXLUÍR EL ARCHIVO .env EN LOS SEGUIMIENTOS DE TU SISTEMA GESTOR DE VERSIONES (.gitignore) SI VAS A COLOCAR EL CÓDIGO EN UN REPOSITORIO.


🔰 CÓMO CONECTAR EL BOT EN MODO "API":


# Se genera una variable con las llaves de autenticación:
auth = tweepy.OAuthHandler(API_KEY, API_SECRET, ACCES_TOKEN, ACCES_TOKEN_SECRET)

# Se crea la conexión y se crea la instancia del bot:
bot = tweepy.API(auth)

❗ NOTA: Este es sólo un método de autenticación; existen muchas variantes que puedes encontrar en LA DOCUMENTACIÓN OFICIAL DE TWEEPY, en donde también encontrarás los cambios y actualizaciones que pueda sufrir en el futuro.


🔰 FUNCIONES VALIOSAS PARA MANIPULAR EL BOT:


1. Publica un tweet de sólo texto:

bot.update_status("¡Que viva Python! 🛐")

2. Recupera en una lista los últimos [10] tweets del usuario @arhcoder:

tweets = bot.user_timeline(screen_name="arhcoder", count=10)
print(f"{tweets[3]}") # <--- Meta-datos del 4to Tweet;

3. Meta-datos que se pueden obtener del "Tweet":

# Toma el último Tweet del usuario "@arhcoder":
tweet = bot.user_timeline(screen_name="arhcoder", count=1)[0]

print("\n\n* ID del Tweet: "+str(tweet.id))
print("\n* Fecha: "+str(tweet.created_at))
print("\n* Texto: "+str(tweet.text))
print("\n* Dispositivo: "+str(tweet.source))
print("\n* Nombre del autor: "+str(tweet.user.name))
print("\n* Foto de perfil del autor: "+str(tweet.user.profile_image_url))
print("\n* Cantidad de seguidores del autor: "+str(tweet.user.followers_count))
print("\n* Cantidad de seguidos del autor: "+str(tweet.user.friends_count))
print("\n* Fecha de creación de la cuenta del autor: "+str(tweet.user.created_at))
print("\n* Arroba del autor: "+str(tweet.user.screen_name))
print("\n* Descripción del autor: "+str(tweet.user.description))
print("\n* Respondió a un Tweet?: "+str(tweet.in_reply_to_status_id))
print("\n* Respondió a un usuario?: "+str(tweet.in_reply_to_user_id))
print("\n* Respondió a un usuario?: "+str(tweet.in_reply_to_screen_name))
print("\n* Cantidad de me gusta: "+str(tweet.favorite_count))
print("\n* Cantidad de me retweets: "+str(tweet.favorite_count))
print("\n* El bot sigue al autor? "+str(tweet.user.following))
#! Y MUCHÍSIMAS OTRAS MÁS CARACTERÍSTICAS #

4. Obtiene un Tweet teniendo su ID:

❗ NOTA: Se puede saber el ID de un Tweet desde su URL; y se puede obtener su URL desde la web, o dando "compartir" desde la aplicación móvil. El ID se extrae tal que así...

unTweet = bot.get_status(id="1460652032994512898")
print(f"\n\n{unTweet}") #<--- Imprime los meta-datos del Tweet;

5. Obtiene información de un usario teniendo su @arroba:

usuario = bot.get_user(screen_name="arhcoder")
print(usuario) # <--- Toda la información del usuario;

6. Envía un mensaje directo:

# Es posible tomar el ID del usuario desde el atributo "id", y es necesario convertirlo a String...
# Sin embargo, el objeto usuario también trae un atributo llamado "id_str", que ya da el ID del usuario en String...
idDelUsuario = str(usuario.id)
idDelUsuario = usuario.id_str
mensaje = "Soy un bot acosador..."

bot.send_direct_message(recipient_id=idDelUsuario, text=mensaje)

7. Publicar Tweet con un archivo multimedia:

❗ NOTAS:

  • Para trabajar con archivos multimedia; tanto para publicarlos en Tweets, como mensajes, como foto de perfil, es necesario usar una función que primero, sube dentro de la API de Twitter, el archivo en cuestión...
  • Ya habiendo subido el archivo multimedia, se obtiene el ID de este al subirlo, y este es el que se adjunta dentro del envío/publicación que querámos hacer.
  • Si se quiere trabajar con un archivo de internet, es necesario primero descargarlo localmente y después subirlo.
  • Para descargar archivos de internet, basta con utilizar requests.

a) Para descargar un archivo de internet con el link de la imágen:

# Nombre del archivo que guardaremos localmente:
nombreArchivo = "michi.jpg"

# Se hace el request:
urlDeLaImagen = "https://cdn2.thecatapi.com/images/df1.jpg"
respuesta = requests.get(urlDeLaImagen, stream=True)

# Si se pudo obtener la respuesta:
if respuesta.status_code == 200:
	# Función que escribe la imágen en el archivo local:
    with open(nombreArchivo, "wb") as archivoLocalDeImagen:
        for pedazo in respuesta:
            archivoLocalDeImagen.write(pedazo)
else:
    print("No se pudo descargar la imágen...")

b) Para subir el archivo a Twiter y obtener su ID:

❗ NOTAS:

  • Restricciones:
    • Imágenes: max 5MB;
    • GIFs: max 15MB;
    • Videos: max 512MB;
  • La función retorna una lista de "Media" pues se pueden agregar varios archivos. A la hora de procesarla es necesario agarrar sólo el primer elemento si querémos sólo una imágen:
# La lista que retorna es de objeto tipo "Media", por lo cuál, si se quiere obtener el ID, se deberá procesar:
listaMedias = bot.media_upload(filename=nombreArchivo)

c) Para publicar el Tweet con la imágen (Sólo un archivo):

# Publica el tweet agregando el ID de la imágen:
# "media_ids" recibe listas de IDs, por lo que si se quiere sólo una, se coloca sólo la que se extrajo anteriormente, entre corchetes []:
bot.update_status(status="🐈 Un mishi bonito: ", media_ids=[listaMedias.media_id_string])

d) Si quieres, puedes hacer que se borre el archivo al descargarlo:

os.remove(nombreArchivo)

8. Publicar Tweet con varios archivos multimedia:

# Lista con todos los archivos a subir en el Tweet:
archivos = ["michi-01.png", "michi-02.jpg", "michi-03.png", "michi-04.jpg"]

# Lista en donde se van a guardar los IDs de las medias:
mediaIDs = []

# Para cada archivo de la lista de archivos:
for archivo in archivos:
	# Sube a twitter el archivo y obten el "Media":
	mediaDelArchivo = bot.media_upload(archivo)

	# Agrega a la lista de medias el id en string del Media del archivo actual:
	mediaIDs.append(mediaDelArchivo.media_id_string)

# Publica el tweet con los archivos que subiste:
bot.update_status(status="🐱‍👤 Un tweet con demasiados gatos :3", media_ids=mediaIDs)

📖 Para complementar el día:

🧰 Recursos: