{"id":15594631,"url":"https://github.com/jofaval/girls4stem-web-scraping","last_synced_at":"2026-05-07T01:09:15.527Z","repository":{"id":232299547,"uuid":"783976747","full_name":"jofaval/girls4stem-web-scraping","owner":"jofaval","description":"girls4stem - Taller parte de la charla de Web Scraping y las Bases de Datos Ofuscadas","archived":false,"fork":false,"pushed_at":"2024-04-15T00:49:36.000Z","size":43,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-06-07T09:35:44.464Z","etag":null,"topics":["java","maven","selenium","testing","web-scraping"],"latest_commit_sha":null,"homepage":"https://girls4stem.uv.es/#/expertaStem#expertsCards","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jofaval.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-04-09T00:13:27.000Z","updated_at":"2024-07-28T09:26:44.000Z","dependencies_parsed_at":"2024-10-03T00:41:22.698Z","dependency_job_id":"ff82309b-f288-4abe-a888-3178d39fcc9b","html_url":"https://github.com/jofaval/girls4stem-web-scraping","commit_stats":null,"previous_names":["jofaval/girls4stem-web-scraping"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/jofaval/girls4stem-web-scraping","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jofaval%2Fgirls4stem-web-scraping","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jofaval%2Fgirls4stem-web-scraping/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jofaval%2Fgirls4stem-web-scraping/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jofaval%2Fgirls4stem-web-scraping/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jofaval","download_url":"https://codeload.github.com/jofaval/girls4stem-web-scraping/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jofaval%2Fgirls4stem-web-scraping/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":275304874,"owners_count":25441165,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-15T02:00:09.272Z","response_time":75,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["java","maven","selenium","testing","web-scraping"],"created_at":"2024-10-03T00:41:14.980Z","updated_at":"2025-09-15T18:44:34.912Z","avatar_url":"https://github.com/jofaval.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# girls4stem\n\n[https://girls4stem.uv.es/#/expertaStem#expertsCards](https://girls4stem.uv.es/#/expertaStem#expertsCards)\n\nParte de la sesión [Web Scraping y las Bases de Datos Ofuscadas](https://github.com/jofaval/talks-about/tree/master/uv/web-scraping-y-las-bases-de-datos-ofuscadas)\n\n## Tabla de contenido\n\n1. [Taller](#taller)\n   1. [Hay qué](#hay-qué)\n   1. [Configuración](#configuración)\n1. [Selenium](#selenium)\n   1. [Qué es](#qué-es)\n   1. [Para qué sirve](#para-qué-sirve)\n   1. [Arquitectura](#arquitectura)\n1. [Alternativas a Selenium](#alternativas-a-selenium)\n   1. [Scrapy](#scrapy)\n      1. [Enlace oficial](#enlace-oficial)\n      1. [Pros](#pros-1)\n      1. [Contras](#contras)\n      1. [Snippet](#snippet)\n   1. [Puppeteer](#puppeteer)\n      1. [Enlace oficial](#enlace-oficial-1)\n      1. [Pros](#pros-1)\n      1. [Contras](#contras-1)\n      1. [Snippet](#snippet-1)\n   1. [Cypress](#cypress)\n      1. [Enlace oficial](#enlace-oficial-2)\n      1. [Pros](#pros-2)\n      1. [Contras](#contras-2)\n      1. [Snippet](#snippet-2)\n   1. [Playwright](#playwright)\n      1. [Enlace oficial](#enlace-oficial-3)\n      1. [Pros](#pros-3)\n      1. [Contras](#contras-3)\n      1. [Snippet](#snippet-3)\n\n## Taller\n\n[Tabla de contenido](#tabla-de-contenido)\n\n### Hay qué\n\n[Taller](#taller)\n\n- Extraer información de todas las expertas de girls4stem\n- Insertar la información siguiendo una estructura de datos razonable\n- Realizar las consultas descritas\n\n### Configuración\n\n[Taller](#taller)\n\n```\nmvn clean install\n```\n\nTras la instalación, Selenium debería estar listo para su uso\n\n### Uso\n\n```\nmvn clean package exec:java\n```\n\n### Testing\n\n```\nmvn package test\n```\n\n## Selenium\n\n[Tabla de contenido](#tabla-de-contenido)\n\nDocumentación oficial:\n\n[https://www.selenium.dev/documentation/](https://www.selenium.dev/documentation/)\n\n### Qué es\n\n[Selenium](#selenium)\n\nHeadless browser con una interfaz para la comunicación entre navegadores.\\\nEs decir, es la suite completa de librería + driver api para poder automatizar acciones con navegadores\n\n### Para qué sirve\n\n[Selenium](#selenium)\n\n- Testing automático y e2e\n- Automatizar procesos rutinarios (fichar en plataformas, iniciar sesión, etc.)\n- Web scraping\n\n### Arquitectura\n\n[Selenium](#selenium)\n\n```mermaid\nflowchart LR\n    A[Driver API - 'Selenium']--\u003e|Simplifica|B[Driver - 'Kernel' del browser]\n    B--\u003e|Se conecta con|C[Headless Browser]\n    C--\u003e|Puede ser|D[Chromium]\n    C--\u003e|Puede ser|E[Firefox Gecko]\n```\n\n1. La API es dependiente del lenguaje que se esté utilizando\n   - La librería podrá cambiar sintaxis aún manteniendo conceptos\n   - El funcionamiento será muy parecido, pero con las peculiaridades de cada lenguaje (Python GIL, Java JVM)\n1. El driver es la conexión específica de la librería con el headless browser, es el elemento común\n   - Java usa un JVM para proporcionar un lenguaje unificado sin importar el Sistema Operativo\n   - Selenium tiene un driver que se conectará con cada navegador (o \"será\" el navegador)\n1. Headless Browser, el _flavor_ del navegador tiene diferencias y soportes, user-agents diferentes, motores diferentes\n   - Teniendo un elemento que unifica conceptos (driver) y una librería que permite comunicarse en varios lenguajes, puede ser que necesitemos diferentes navegadores, ahí entran los navegadores que queramos usar\n   - Google Chrome usa el motor de Chromium (y la mayoría de los navegadores también), Firefox tiene su propio motor (Gecko), y Safari también (WebKit)\n\n## Alternativas a Selenium\n\n[Tabla de contenido](#tabla-de-contenido)\n\nNo es la única opción del mercado, pero sí la más conocida.\\\nY agnóstica hasta cierto punto con respecto al lenguaje necesario\n\nEl código que se muestra es de **ejemplo**. ¡¡No va a funcionar!!\n\n### Scrapy\n\n[Alternativas a Selenium](#alternativas-a-selenium)\n\n#### Enlace oficial\n\n[Scrapy](#scrapy)\n\nhttps://scrapy.org/\n\n#### Pros\n\n[Scrapy](#scrapy)\n\n- Usa Python, es decir, se puede usar en Google Colab sin mayor inconveniente\n- Es una librería de utilidades, no un driver, por lo que la instalación y configuración es relativamente sencilla\n- Está preparada específicamente para web scraping\n\n#### Contras\n\n[Scrapy](#scrapy)\n\n- Requiere clases, lo cuál no es malo por defecto, pero cuando es una imposición, y más en Python que no todo son clases, es un gomet negativo\n- Las configuraciones van ligadas a archivos físicos (a veces), por lo que ni puede ser un único notebook, ni un único fichero de script\n- Toda librería abstrae, pero toda abstracción siempre tiene una fuga\n\n#### Snippet\n\n[Scrapy](#scrapy)\n\nDirecto de la documentación\n\n```python\nimport scrapy\n\nclass BlogSpider(scrapy.Spider):\n    name = 'blogspider'\n    start_urls = ['https://www.zyte.com/blog/']\n\n    def parse(self, response):\n        for title in response.css('.oxy-post-title'):\n            yield {'title': title.css('::text').get()}\n\n        for next_page in response.css('a.next'):\n            yield response.follow(next_page, self.parse)\n\nEOF\n```\n\n### Puppeteer\n\n[Alternativas a Selenium](#alternativas-a-selenium)\n\n#### Enlace oficial\n\n[Puppeteer](#puppeteer)\n\nhttps://pptr.dev/\n\n#### Pros\n\n[Puppeteer](#puppeteer)\n\n- Usa JavaScript y Node por lo que hay un montón de documentación de lenguaje (y utilidades de alto nive, MapReduce por ejemplo)\n- Usar JavaScript ofrece una integración con el DOM más cercana\n- Es un headless browser, está pensado para testing e2e (similar a Selenium)\n\n#### Contras\n\n[Puppeteer](#puppeteer)\n\n- JavaScript no es perfecto, ni el lenguaje más rápido, además, necesita de TypeScript para añadir tipados\n- Requiere de Node para poder funcionar, y aunque Node sea útil, también es problemático a ratos\n- Está pensado para testing, por lo que toda integración para web scraping se crea _ad hoc_\n\n#### Snippet\n\n[Puppeteer](#puppeteer)\n\nModificado de la documentación\n\n```javascript\nimport puppeteer from \"puppeteer\";\n\n(async () =\u003e {\n  const browser = await puppeteer.launch();\n  const page = await browser.newPage();\n\n  await page.goto(\"https://developer.chrome.com/\");\n\n  await page.waitForSelector(\".devsite-result-item-link\");\n  await page.click(searchResultSelector);\n\n  const fullTitle = await textSelector?.evaluate((el) =\u003e el.textContent);\n\n  await browser.close();\n})();\n```\n\n### Cypress\n\n[Alternativas a Selenium](#alternativas-a-selenium)\n\n#### Enlace oficial\n\n[Cypress](#cypress)\n\nhttps://www.cypress.io/\n\n#### Pros\n\n[Cypress](#cypress)\n\n- JavaScript + Node, más cerca del DOM\n- No está pensado para web scraping, pero tiene utilidades de DOM (que nos vienen bien\n- Muy reconocido dentro del ecosistema de Node\n- API bastante simple\n\n#### Contras\n\n[Cypress](#cypress)\n\n- JavaScript no es perfecto, ni el lenguaje más rápido, además, necesita de TypeScript para añadir tipados\n- Requiere de Node para poder funcionar, y aunque Node sea útil, también es problemático a ratos\n- Está pensado para testing, por lo que toda integración para web scraping se crea _ad hoc_\n\n#### Snippet\n\n[Cypress](#cypress)\n\n```javascript\ncy.visit(\"http://localhost:8080\");\nconst element = cy.contains(\"querySelector\");\nelement.contains(\"a\").click();\n```\n\n### Playwright\n\n[Alternativas a Selenium](#alternativas-a-selenium)\n\n#### Enlace oficial\n\n[Playwright](#playwright)\n\nhttps://playwright.dev/\n\n#### Pros\n\n[Playwright](#playwright)\n\n- JavaScript + Node, más cerca del DOM\n- No está pensado para web scraping, pero tiene utilidades de DOM (que nos vienen bien)\n- Playwright es parecido a Cypress, pero con mayor rendimiento\n\n#### Contras\n\n[Playwright](#playwright)\n\n- JavaScript no es perfecto, ni el lenguaje más rápido, además, necesita de TypeScript para añadir tipados\n- Requiere de Node para poder funcionar, y aunque Node sea útil, también es problemático a ratos\n- Está pensado para testing, por lo que toda integración para web scraping se crea _ad hoc_\n- La sintáxis es un poco más enrevesada que la de Cypress\n\n#### Snippet\n\n[Playwright](#playwright)\n\nDirecto de la documentación\n\n```javascript\nimport { test, expect } from \"@playwright/test\";\n\ntest(\"has title\", async ({ page }) =\u003e {\n  await page.goto(\"https://playwright.dev/\");\n\n  await expect(page).toHaveTitle(/Playwright/);\n});\n\ntest(\"get started link\", async ({ page }) =\u003e {\n  await page.goto(\"https://playwright.dev/\");\n\n  await page.getByRole(\"link\", { name: \"Get started\" }).click();\n\n  await expect(\n    page.getByRole(\"heading\", { name: \"Installation\" })\n  ).toBeVisible();\n});\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjofaval%2Fgirls4stem-web-scraping","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjofaval%2Fgirls4stem-web-scraping","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjofaval%2Fgirls4stem-web-scraping/lists"}