paint-brush
Dramaturgo: mis primeros pasos con la herramienta de automatización del navegadorpor@nfrankel
512 lecturas
512 lecturas

Dramaturgo: mis primeros pasos con la herramienta de automatización del navegador

por Nicolas Fränkel
Nicolas Fränkel HackerNoon profile picture

Nicolas Fränkel

@nfrankel

Developer Advocate, eternal learner, author

7 min read2025/01/26
Read on Terminal Reader
Read this story in a terminal
Print this story
tldt arrow
es-flagES
Lee esta historia en Español!
en-flagEN
Read this story in the original language, English!
de-flagDE
Lesen Sie diese Geschichte auf Deutsch!
vi-flagVI
Đọc bài viết này bằng tiếng Việt!
ja-flagJA
この物語を日本語で読んでください!
bs-flagBS
Pročitajte ovu priču na bosanskom!
tg-flagTG
Ин қиссаро бо забони тоҷикӣ хонед!
sr-flagSR
Прочитајте ову причу на српском!
so-flagSO
Sheekadan Af-Soomaali ku akhri!
lv-flagLV
Izlasi šo stāstu latviešu valodā!
lo-flagLO
ອ່ານເລື່ອງນີ້ເປັນພາສາລາວ!
ta-flagTA
இந்த கதையை தமிழில் படியுங்கள்!
th-flagTH
อ่านเรื่องนี้เป็นภาษาไทย!
ES

Demasiado Largo; Para Leer

Algunos medios no ofrecen una API HTTP para las métricas que deseo. Playwright es una herramienta de automatización del navegador con un par de API de lenguaje, incluido Python. Ofrece dos API distintas, una sincrónica y otra asincrónica.
featured image - Dramaturgo: mis primeros pasos con la herramienta de automatización del navegador
Nicolas Fränkel HackerNoon profile picture
Nicolas Fränkel

Nicolas Fränkel

@nfrankel

Developer Advocate, eternal learner, author

En mi empresa anterior, desarrollé un trabajo por lotes que rastreaba métricas en redes sociales, como Twitter, LinkedIn, Mastodon, Bluesky, Reddit, etc. Luego me di cuenta de que podía duplicarlo para mi propia "personalidad". El problema es que algunos medios no ofrecen una API HTTP para las métricas que quiero. Estas son las métricas que quiero en LinkedIn:


Panel de métricas de LinkedIn

Panel de métricas de LinkedIn


Busqué durante mucho tiempo, pero no encontré acceso a la API para las métricas anteriores. Busqué las métricas manualmente todas las mañanas durante mucho tiempo y finalmente decidí automatizar esta tediosa tarea. Esto es lo que aprendí.

El contexto

El trabajo se realiza en Python, por lo que quiero mantenerme en la misma pila tecnológica. Después de una rápida investigación, encontré Playwright , una herramienta de automatización del navegador con un par de API de lenguaje, incluido Python. El caso de uso principal de Playwright es la prueba de extremo a extremo, pero también puede administrar el navegador fuera de un contexto de prueba.


Estoy usando Poetry para administrar las dependencias. Instalar Playwright es tan fácil como:


 poetry add playwright


En este punto, Playwright está listo para usarse. Ofrece dos API distintas, una sincrónica y otra asincrónica . Debido a mi caso de uso, la primera versión es más que suficiente.

Mojándome los pies

Me gusta abordar el desarrollo de forma incremental.


A continuación se muestra un extracto de la API:


Extracto del modelo API

Extracto del modelo API


Se traduce al siguiente código:


 from playwright.sync_api import Browser, Locator, Page, sync_playwright with (sync_playwright() as pw): #1 browser: Browser = pw.chromium.launch() #2 page: Page = browser.new_page() #3 page.goto('https://www.linkedin.com/login') #4 page.locator('#username').press_sequentially(getenv('LINKEDIN_USERNAME')) #5 page.locator('#password').press_sequentially(getenv('LINKEDIN_PASSWORD')) #5 page.locator('button[type=submit]').press('Enter') #6 page.goto('https://www.linkedin.com/dashboard/') #4 metrics_container: Locator = page.locator('.pcd-analytic-view-items-container') metrics: List[Locator] = metrics_container.locator('p.text-body-large-bold').all() #7 impressions = atoi(metrics[0].inner_text()) #8 # Get other metrics browser.close() #9
  1. Consigue un objeto playwright .


  2. Inicie una instancia del navegador. Hay varios tipos de navegadores disponibles; elegí Chromium por capricho. Tenga en cuenta que debería haber instalado el navegador específico previamente, es decir , playwright install --with-deps chromium .


    De forma predeterminada, el navegador se abre sin interfaz gráfica , no aparece. Te recomiendo ejecutarlo de forma visible al principio para facilitar la depuración: headless = True .


  3. Abra una nueva ventana del navegador.


  4. Navegar a una nueva ubicación.


  5. Localice los campos de entrada especificados y complételos con mis credenciales.


  6. Localice el botón especificado y presiónelo.


  7. Localizar todos los elementos especificados.


  8. Obtenga el texto interno del primer elemento.


  9. Cierre el navegador para limpiar.

Almacenamiento de cookies

Lo anterior funcionó como se esperaba. El único inconveniente es que recibí un correo electrónico de LinkedIn cada vez que ejecuté el script:


Hola Nicolás,


Has activado con éxito Recordarme en un nuevo dispositivo HeadlessChrome, <OS> en <ciudad>, <región>, <país >. Obtén más información sobre cómo funciona Recordarme en un dispositivo.


También conocí a Fabien Vauchelles en la conferencia JavaCro . Se especializa en web scraping y me dijo que la mayoría de las personas en este campo aprovechan los perfiles del navegador. De hecho, si inicias sesión en LinkedIn, obtendrás un token de autenticación almacenado como cookies y no necesitarás autenticarlo nuevamente antes de que caduque. Afortunadamente, Playwright ofrece esa función con su método launch_persistent_context .


Podemos reemplazar el launch anterior por el siguiente:


 with sync_playwright() as pw: playwright_profile_dir = f'{Path.home()}/.social-metrics/playwright-profile' context: BrowserContext = pw.chromium.launch_persistent_context(playwright_profile_dir) #1 try: #2 page: Page = context.new_page() #3 page.goto('https://www.linkedin.com/dashboard/') #4 if 'session_redirect' in page.url: #4 page.locator('#username').press_sequentially(getenv('LINKEDIN_USERNAME')) page.locator('#password').press_sequentially(getenv('LINKEDIN_PASSWORD')) page.locator('button[type=submit]').press('Enter') page.goto('https://www.linkedin.com/dashboard/') metrics_container: Locator = page.locator('.pcd-analytic-view-items-container') # Same as in the previous snippet except Exception as e: #2 logger.error(f'Could not fetch metrics: {e}') finally: #5 context.close()
  1. Playwright almacenará el perfil en la carpeta especificada y lo reutilizará en cada ejecución.


  2. Mejorar el manejo de excepciones.


  3. BrowserContext también puede abrir páginas.


  4. Intentamos navegar hasta el panel de control. LinkedIn nos redireccionará a la página de inicio de sesión si no estamos autenticados; entonces podremos autenticarnos.


  5. Cerrar el contexto sea cual sea el resultado.


En este punto, solo necesitamos autenticarnos con ambas credenciales la primera vez. En ejecuciones posteriores, depende.

Adaptarse a la realidad

Me sorprendió ver que el código anterior no funcionaba de manera confiable. Funcionó en la primera ejecución y, a veces, en las posteriores. Debido a que estoy almacenando el perfil del navegador en varias ejecuciones, cuando necesito autenticarme, LinkedIn solo solicita la contraseña, ¡no el nombre de usuario! Debido a que el código intenta ingresar el nombre de usuario, falla en este caso. La solución es bastante sencilla:


 username_field = page.locator('#username') if username_field.is_visible(): username_field.press_sequentially(getenv('LINKEDIN_USERNAME')) page.locator('#password').press_sequentially(getenv('LINKEDIN_PASSWORD'))

Conclusión

Aunque no soy un experto en Python, logré lo que quería con Playwright. Preferí usar la API de sincronización porque hace que el código sea un poco más fácil de entender y no tengo ningún requisito de rendimiento. Solo utilicé las funciones básicas que ofrece Playwright. Playwright permite grabar videos en el contexto de las pruebas, lo que es muy útil cuando una prueba falla durante la ejecución de una secuencia de comandos de CI.


Para ir más allá:



Publicado originalmente en A Java Geek el 19 de enero de 2024

L O A D I N G
. . . comments & more!

About Author

Nicolas Fränkel HackerNoon profile picture
Nicolas Fränkel@nfrankel
Developer Advocate, eternal learner, author

ETIQUETAS

ESTE ARTÍCULO FUE PRESENTADO EN...

Read on Terminal Reader
Read this story in a terminal
 Terminal
Read this story w/o Javascript
Read this story w/o Javascript
 Lite
Also published here
X REMOVE AD