Preguntas comunes sobre Web Scraping - Respuestas y consejos

Mihai Maxim el 03 mar 2023

blog-image

Navegar por el mundo del web scraping puede ser un poco abrumador. Hay que elegir el lenguaje de programación y la biblioteca adecuados, y enfrentarse a muchos contratiempos imprevistos. Rápidamente se convierte en mucho que asimilar. Pero que eso no te desanime. En este artículo, he respondido a algunas de las preguntas más frecuentes sobre el web scraping. Aprenderás lo que otras personas están haciendo y los retos a los que se han enfrentado. Esto te ayudará a tomar tus propias decisiones. Tanto si eres nuevo en este campo como un profesional experimentado, aquí hay algo para todos.

¿Por qué mi scraper no puede ver los mismos datos que mi navegador?

You've written a script to fetch HTML from a website, but you're not getting the full data. You've tested your selectors in the browser and they should work, right? Not always. Websites that rely on JavaScript to render won't work with a simple GET request. There are libraries like Puppeteer and Selenium that use headless browsers to render JavaScript. They allow you to make the request in the context of a browser and wait for JavaScript to finish executing. This way, you can get the full HTML. You may not always need a headless browser to get the missing data. Search for <script> tags in the HTML. The missing data could be hidden inside <script> tags as JavaScript variables.

¿Cómo puedo scrapear un sitio web que utiliza clases CSS generadas?

Algunos sitios web utilizan bibliotecas que crean automáticamente nombres de clase únicos para los distintos componentes de la página. Esto puede dificultar el uso de selectores CSS tradicionales para apuntar a elementos específicos.

Una solución es utilizar expresiones XPath en su lugar. Los selectores XPath se basan en el diseño de la página, en lugar de en nombres de clase específicos. Esto significa que aunque cambien los nombres de las clases, el selector XPath podrá localizar el elemento deseado.

Por ejemplo, si tiene un componente HTML con el siguiente aspecto:

<div class="container">

<div class="subcontainer_af21">

<ul class="ul_ax1">

<li class="li_adef">

<a href="https://link1">Winter Storm</a>

</li>

</ul>

<ul class="ul_cgt4">

<li class="li_ocv2">

<a href="https://lin2">SpaceX</a>

</li>

</ul>

</div>

</div>

You can select the second <a> element with:

//div[@class='container']/div/ul[2]/li/a

¿Es Cheerio más rápido que Puppeteer?

Sí, en general se considera que Cheerio es más rápido que Puppeteer. Esto se debe a que Cheerio es una biblioteca del lado del servidor que trabaja directamente con el contenido HTML. Puppeteer es una biblioteca de automatización del navegador que controla un navegador sin cabeza para cargar páginas web e interactuar con ellas. Cheerio está limitado en el sentido de que sólo puede trabajar con páginas estáticas, no tiene la capacidad de interactuar con el navegador como lo hace Puppeteer.

¿Son los selectores XPath mejores que los selectores CSS?

Depende del contexto. Si busca extraer datos basados en la posición de los elementos, XPath es la mejor opción. Sin embargo, si busca extraer datos basados en propiedades como clase o id, los selectores CSS son una mejor opción.

¿Es Playwright mejor que Puppeteer?

Ambos ofrecen funcionalidades similares, pero. Playwright es compatible con varios navegadores, como Chrome, Firefox y Safari. Puppeteer solo es compatible con Chrome y Chromium.

Playwright tiene mejor soporte para trabajar con múltiples pestañas y ventanas. También tiene soporte integrado para manejar contextos de navegador, cookies y almacenamiento. Playwright es más adecuado para proyectos complejos.

¿Cómo puedo evitar las prohibiciones de IP?

En general, puedes intentar espaciar tus peticiones. Utiliza diferentes IPs. Utilice proxies. Intentar modificar la huella digital del navegador. Para la mayoría de la gente, esta es una batalla interminable. La buena noticia es que no tiene por qué ser así. Puede utilizar nuestra solución, WebScrapingAPI. WebScrapingAPI proporciona una API que se encargará de todo el trabajo pesado por usted. Puede ejecutar JavaScript, rotar proxies, e incluso manejar CAPTCHAs. Nunca tendrás que preocuparte de que baneen tu IP. Pero no nos creas. Puedes probarlo gratis.

¿Cómo extraer texto de HTML con BeautifulSoup?

Puede utilizar la biblioteca BeautifulSoup. He aquí un ejemplo de extracción de texto utilizando la función .get_text():

from bs4 import BeautifulSoup

html_doc = """

<html>

<head>

<title>title of the page</title>

</head>

<body>

<p>a paragraph</p>

<a href='https://link.com'>a link</a>

</body>

</html>

"""

soup = BeautifulSoup(html_doc, 'html.parser')

paragraph_text = soup.find('p').text

print(paragraph_text)

#Prints 'a paragraph'

link_text = soup.find('a').text

print(link_text)

#Prints 'a link'

all_text = soup.get_text()

print(all_text)

"""

title of the page

a paragraph

a link

"""

¿Cómo extraer texto de HTML con Selenium?

He aquí cómo hacerlo en Selenium:

from selenium import webdriver

from selenium.webdriver.common.by import By

DRIVER_PATH = 'path/to/chromedriver'

driver = webdriver.Chrome(executable_path=DRIVER_PATH)

driver.get("https://en.wikipedia.org/wiki/Main_Page")

# obtiene todos los elementos h2

content = driver.find_element(By.TAG_NAME, "h2")

print(content.text)

# imprime 'Del artículo destacado de hoy'

¿Cómo seleccionar elementos HTML por texto con BeautifulSoup?

With BeautifulSoup, you can use the soup.find method with the text=re.compile("<text>") parameter:

from bs4 import BeautifulSoup

import re

html_doc = """

<html>

<body>

<p class="my_paragraph">a paragraph.</p>

<p class="my_paragraph">another paragraph.</p>

</body>

</html>

"""

soup = BeautifulSoup(html_doc, 'html.parser')

# find the first pTag that contains the text 'a par'

pTag = soup.find("p", text=re.compile("a par"))

print(pTag)

¿Cómo seleccionar elementos HTML por texto con Selenium?

En Selenium, puede hacerlo con XPath:

from selenium import webdriver

from selenium.webdriver.common.by import By

DRIVER_PATH = 'path/to/chromedriver'

driver = webdriver.Chrome(executable_path=DRIVER_PATH)

driver.get("https://en.wikipedia.org/wiki/Main_Page")

# obtiene todos los elementos con clase vector-body

span = driver.find_element(By.XPATH, "//span[contains(text(), 'Did')]")

print(span.text)

# Imprime 'Sabías que...'

driver.quit()

¿Cómo encontrar elementos HTML con selectores CSS en BeautifulSoup?

Así es como puedes hacerlo con BeautifulSoup y los métodos find y find_all:

from bs4 import BeautifulSoup

html_doc = """

<html>

<body>

<p class="my_paragraph">First paragraph.</p>

<p class="my_paragraph">Second paragraph..</p>

<p>Last paragraph.</p>

</body>

</html>

"""

soup = BeautifulSoup(html_doc, 'html.parser')

# find all elements with class 'my_paragraph

elements = soup.find_all(class_="my_paragraph")

for element in elements:

print(element.text)

# prints 'First paragraph.' and 'Second paragraph..'

¿Cómo encontrar elementos HTML por clase con Selenium?

A continuación se explica cómo hacerlo con Selenium:

from selenium import webdriver

from selenium.webdriver.common.by import By

DRIVER_PATH = 'path/to/chromedriver'

driver = webdriver.Chrome(executable_path=DRIVER_PATH)

driver.get("https://en.wikipedia.org/wiki/Página_principal")

# obtener todos los elementos con clase vector-body

elements = driver.find_elements(By.CLASS_NAME, "vector-body")

for element in elements:

print(element.text)

driver.quit()

¿Cómo utilizar XPath con BeautifulSoup?

Necesitará la biblioteca lxml Python:

import requests

from bs4 import BeautifulSoup

from lxml import etree

response = requests.get("https://en.wikipedia.org/wiki/Main_Page")

soup = BeautifulSoup(response.content, 'html.parser')

dom = etree.HTML(str(body))

xpath_str = '//h1//text()'

print(dom.xpath(xpath_str))

#Prints ['Página principal', 'Bienvenido a ', 'Wikipedia']

¿Cómo esperar a que se cargue la página en Selenium?

Si simplemente quieres esperar un tiempo determinado antes de que se agote el tiempo al intentar encontrar cualquier elemento, puedes utilizar la función driver.implicitly_wait(time_in_secods):

from selenium import webdriver

from selenium.webdriver.common.by import By

DRIVER_PATH = 'C:/Users/Michael/Desktop/chromedriver'

driver = webdriver.Chrome(executable_path=DRIVER_PATH)

driver.implicitly_wait(10)

driver.get("https://en.wikipedia.org/wiki/Main_Page")

element = driver.find_element(By.ID, "not_found_id")

# el elemento no existe, pero espera 10 segundos por él

text = element.text

print(text)

# Cierra el navegador

driver.quit()

También puede optar por esperar hasta que se cumpla una determinada condición:

from selenium import webdriver

from selenium.webdriver.common.by import By

from selenium.webdriver.support.ui import WebDriverWait

from selenium.webdriver.support import expected_conditions as EC

DRIVER_PATH = 'C:/Users/Michael/Desktop/chromedriver'

driver = webdriver.Chrome(executable_path=DRIVER_PATH)

driver.get("https://en.wikipedia.org/wiki/Página_principal")

# Espera a que el elemento con id 'content' esté presente en la página

wait = WebDriverWait(driver, 10)

element = wait.until(EC.presence_of_element_located((By.ID, "content")))

element = driver.find_element(By.ID, "content")

text = element.text

print(text)

# Cerrar el navegador

driver.quit()

¿Cómo encontrar elementos HTML con selectores CSS en Puppeteer?

En Puppeteer, puede utilizar las funciones page.$() y page.$$() para seleccionar elementos con selectores CSS. La función page.$() se utiliza para encontrar el primer elemento que coincide con el selector. La función page.$$() se utiliza para encontrar todos los elementos que coinciden con el selector.

const puppeteer = require('puppeteer');

(async () => {

const browser = await puppeteer.launch({

headless: false,

});



const page = await browser.newPage();

await page.goto('https://www.scrapethissite.com/pages/simple/');

// Extract the first odd row element

const firstOddRow = await page.$('.container .row');

console.log(await firstOddRow.evaluate(node => node.textContent));

// Extract all the odd rows

const allOddRows = await page.$$('.container .row');

for (const oddRow of allOddRows) {

console.log(await oddRow.evaluate(node => node.textContent));

}

await browser.close();

})();

¿Cómo encontrar elementos HTML con selectores CSS en Playwright?

A continuación se explica cómo hacerlo con Playwright. Es muy similar a Puppeteer:

const { chromium } = require('playwright');

(async () => {

const browser = await chromium.launch({

headless: false,

});

const context = await browser.newContext();

const page = await context.newPage();

await page.goto('https://www.scrapethissite.com/pages/simple/');

// Extract the first odd row element

const firstOddRow = await page.$('.container .row');

console.log(await firstOddRow.textContent());

// Extract all the odd rows

const allOddRows = await page.$$('.container .row');

for (const oddRow of allOddRows ) {

console.log(await oddRow.textContent());

}

await browser.close();

})();

¿Cómo encontrar elementos HTML con selectores CSS en cheerio?

Con cheerio, tendrás que obtener el HTML (para eso usé la biblioteca request) y luego pasarlo a la biblioteca cheerio:

const request = require('request');

const cheerio = require('cheerio');

const url = 'https://www.scrapethissite.com/pages/simple/';

request(url, (error, response, html) => {

if (!error && response.statusCode === 200) {

const $ = cheerio.load(html);

const firstOddRow = $('.container .row').first();

console.log(firstOddRow.text());

const allOddRows = $('.container .row');

allOddRows.each((i, oddRow) => {

console.log($(oddRow).text());

});

}

});

¿Cómo utilizar XPath con Puppeteer?

Con Puppeteer, puede utilizar la función page.$x() para seleccionar elementos con selectores XPath:

const puppeteer = require('puppeteer');

(async () => {

const browser = await puppeteer.launch();

const page = await browser.newPage();

await page.goto('https://www.scrapethissite.com/pages/forms/');

// Extract the table header elements

const allTableHeaders = await page.$x('//table/tbody/tr[1]//th');

for(let i = 0; i < allTableHeaders.length; i++) {

const header = await page.evaluate(el => el.textContent, allTableHeaders[i]);

console.log(header.trim());

}

await browser.close();

})();

// Output:

// Team Name

// Year

// Wins

// Losses

// OT Losses

// Win %

// Goals For (GF)

// Goals Against (GA)

// + / -

¿Cómo utilizar XPath con Playwright?

const { chromium } = require('playwright');

(async () => {

const browser = await chromium.launch({

headless: false,

});

const context = await browser.newContext();

const page = await context.newPage();

await page.goto('https://www.scrapethissite.com/pages/forms/');

// Extract the table header elements

const allTableHeaders = await page.locator('xpath=//table/tbody/tr[1]//th').all();



for (let i = 0; i < allTableHeaders.length; i++) {

const headerText = await allTableHeaders[i].innerText();

console.log(headerText);

}

await browser.close();

})();

Se asume que cualquier cadena de selector que empiece por // o .. es un selector xpath. Por ejemplo, Playwright convierte '//html/body' en 'xpath=//html/body'.

¿Cómo encontrar elementos HTML por texto en Puppeteer?

En Puppeteer, la forma más sencilla de encontrar elementos por texto es utilizar la función XPath text():

const puppeteer = require('puppeteer');

(async () => {

const browser = await puppeteer.launch({

headless: false,

});

const page = await browser.newPage();

await page.goto('https://en.wikipedia.org/wiki/Web_scraping');

// Select all the p tags texts that contain the word "prevent"

const pTags = await page.$x('//p[contains(text(), "prevent")]/text()');

for(let i = 0; i < pTags.length; i++) {

const pTag = await page.evaluate(el => el.textContent, pTags[i]);

console.log(pTag,"\n");

}

await browser.close();

})();

//Output:

There are methods that some websites use to prevent web scraping, such as detecting and disallowing bots from crawling (viewing) their pages. In response, there are web scraping systems that rely on using techniques in ...

¿Cómo encontrar elementos HTML por texto en Playwright?

Si desea buscar elementos por texto en Playwright, puede utilizar la función allInnerTexts() en combinación con XPath.

const { chromium } = require('playwright');

(async () => {

const browser = await chromium.launch({

headless: false,

});

const context = await browser.newContext();

const page = await context.newPage();

await page.goto('https://en.wikipedia.org/wiki/Web_scraping');

// Select all the p tags texts that contain the word "prevent"

const pTags = await page.locator('//p[contains(text(), "prevent")]').allInnerTexts();



for (let i = 0; i < pTags.length; i++) {

console.log(pTags[i], "\n");

}

await browser.close();

})();

¿Cómo encontrar elementos HTML por texto en cheerio?

const request = require('request');

const cheerio = require('cheerio');

const url = 'https://en.wikipedia.org/wiki/Web_scraping';

request(url, (error, response, html) => {

if (!error && response.statusCode === 200) {

const $ = cheerio.load(html);

// Select all the p tags texts that contain the word "prevent"

const elements = $('p').filter((i, el) => $(el).text().includes('prevent'));

elements.each((i, el) => {

console.log($(el).text());

});

}

});

¿Cómo esperar a los selectores en Puppeteer?

En Puppeteer, puede utilizar la función page.waitForSelector() para esperar a que un elemento específico aparezca en la página antes de continuar con el script. Puede utilizarla tanto con selectores CSS como XPath:

await page.waitForSelector('.basic-element', { timeout: 10000 });

await page.waitForXPath("//div[@class='basic-element']"), { timeout: 10000 });

El parámetro timeout especifica el tiempo máximo de espera en ms.

También puede esperar a que un elemento alcance un determinado estado:

await page.waitForSelector('.basic-element', { visible: true });

// wait until the element becomes visible

¿Cómo esperar a los selectores en Playwright?

Playwright es similar a Puppeteer. Puede utilizar el método page.waitForSelector() para esperar a que aparezca un elemento específico en la página.

await page.waitForSelector('.element-class', { timeout: 10000 });

También puede esperar a que un elemento alcance un determinado estado:

 await page.waitForSelector('.basic-element', { state: 'visible' });

// wait for element to become visible

Conclusión

El raspado web es un tema muy amplio y este artículo sólo cubre la superficie. La elección de la herramienta adecuada para su caso de uso específico es crucial. Por ejemplo, si quieres hacer scraping de un sitio web usando JavaScript, la librería cheerio es una buena opción. Sin embargo, si el sitio web requiere JavaScript para cargar completamente, Puppeteer o Playwright son mejores opciones. El web scraping es un reto, pero entender las herramientas puede ahorrarte muchos dolores de cabeza. Espero que este artículo haya ampliado su perspectiva y le deseo lo mejor en sus esfuerzos de web scraping.

Noticias y actualidad

Manténgase al día de las últimas guías y noticias sobre raspado web suscribiéndose a nuestro boletín.

We care about the protection of your data. Read our <l>Privacy Policy</l>.Privacy Policy.

Artículos relacionados

miniatura
GuíasCómo raspar datos de productos de Amazon: Guía completa de mejores prácticas y herramientas

Explore las complejidades del scraping de datos de productos de Amazon con nuestra guía en profundidad. Desde las mejores prácticas y herramientas como Amazon Scraper API hasta las consideraciones legales, aprenda a superar los desafíos, eludir los CAPTCHA y extraer información valiosa de forma eficiente.

Suciu Dan
avatar de autor
Suciu Dan
15 minutos de lectura
miniatura
Ciencia del Web ScrapingScrapy vs. Selenium: Guía completa para elegir la mejor herramienta de Web Scraping

Explore la comparación en profundidad entre Scrapy y Selenium para el scraping web. Desde la adquisición de datos a gran escala hasta la gestión de contenido dinámico, descubra los pros, los contras y las características únicas de cada uno. Aprenda a elegir el mejor marco de trabajo en función de las necesidades y la escala de su proyecto.

WebscrapingAPI
avatar de autor
WebscrapingAPI
14 min leer
miniatura
GuíasScrapy vs. Beautiful Soup: Guía comparativa completa de herramientas de raspado web

Explore una comparación detallada entre Scrapy y Beautiful Soup, dos herramientas líderes de raspado web. Comprende sus características, pros y contras, y descubre cómo pueden utilizarse juntas para adaptarse a las necesidades de distintos proyectos.

WebscrapingAPI
avatar de autor
WebscrapingAPI
10 minutos de lectura