Una importante habilidad para obtener datos de páginas web es el web scraping. Pinterest e Instagram, que cargan contenidos de forma dinámica gracias a la interacción de los usuarios con ellos, son ejemplos de este tipo de sitios web. Los métodos de scraping habituales son insuficientes cuando se maneja material basado en JavaScript. En este artículo, hablaremos de Playwright como herramienta de automatización, mientras que lxml se utilizará para la extracción de datos de este tipo de sitios dinámicos que requieren Javascript para funcionar correctamente. En esta nota, podemos discutir la utilización de proxies en Playwright para evadir la detección como bots. En este tutorial, vamos a scrapear el perfil de Instagram para recuperar todas las URLs de las publicaciones simulando el comportamiento del usuario, como desplazarse y esperar a que se carguen las publicaciones.
Herramientas que usaremos en esta guía:
Ilustraremos el proceso con el ejemplo de scrapear un perfil de Instagram para extraer URLs de posts, simulando acciones del usuario como desplazarse por la página y esperar a que se carguen nuevos datos. Los sitios web dinámicos cargan su contenido de forma asíncrona mediante peticiones AJAX, lo que significa que no todo el contenido de la página es accesible de forma inmediata.
Antes de empezar, instala los paquetes necesarios:
pip install playwright
pip install lxml
También tendrás que instalar los navegadores Playwright:
playwright install
Usaremos Playwright para automatizar el navegador, cargar el contenido dinámico de Instagram y desplazarnos por la página para cargar más publicaciones. Vamos a crear un script básico de automatización:
Script de automatización (Headless Browser):
import asyncio
from playwright.async_api import async_playwright
async def scrape_instagram():
async with async_playwright() as p:
browser = await p.chromium.launch(headless=True) # Modo sin cabeza Sin respuesta visual
page = await browser.new_page()
# Visite la URL del perfil
await page.goto("https://www.instagram.com/profile name/", wait_until="networkidle")
# Haga clic en el botón para cargar más mensajes
await page.get_by_role("button", name="Show more posts from").click()
# Desplazar la página para cargar contenido dinámico
scroll_count = 5 # Personalízalo en función de las veces que quieras desplazarte
for _ in range(scroll_count):
await page.evaluate('window.scrollBy(0, 700);')
await page.wait_for_timeout(3000) # Esperar a que se carguen los mensajes
await page.wait_for_load_state("networkidle")
# Obtener el contenido de la página
content = await page.content()
await browser.close()
return content
# Ejecutar la función asíncrona
asyncio.run(scrape_instagram())
Una vez cargado el contenido, podemos usar lxml para parsear el HTML y extraer datos usando XPath. En este caso, estamos extrayendo las URLs de todos los posts del perfil.
Parseando el contenido de la página y extrayendo las URLs de los posts:
from lxml import html
import json
def extract_post_urls(page_content):
# Analiza el contenido HTML con lxml
tree = html.fromstring(page_content)
# XPath para extraer las URL de las entradas
post_urls_xpath = '//a[contains(@href, "/p/")]/@href'
# Extraer URL
post_urls = tree.xpath(post_urls_xpath)
# Convertir URL relativas en absolutas
base_url = "https://www.instagram.com"
post_urls = [f"{base_url}{url}" for url in post_urls]
return post_urls
Función de ejemplo para guardar los datos extraídos en formato JSON:
def save_data(profile_url, post_urls):
data = {profile_url: post_urls}
with open('instagram_posts.json', 'w') as json_file:
json.dump(data, json_file, indent=4)
# Raspar y extraer URL
page_content = asyncio.run(scrape_instagram())
post_urls = extract_post_urls(page_content)
# Guardar las URL extraídas en un archivo JSON
save_data("https://www.instagram.com/profile name/", post_urls)
Para scrapear sitios web dinámicos, a menudo es necesario simular un scroll infinito. En nuestro script, desplazamos la página usando JavaScript:
(window.scrollBy(0, 700))
Y espera a que se cargue el nuevo contenido usando este comando:
wait_for_load_state("networkidle")
Instagram tiene estrictos límites de tasa y medidas anti-bot. Para evitar que te bloqueen, puedes utilizar proxies para rotar las direcciones IP y distribuir las solicitudes. Playwright facilita la integración de proxies en tu automatización de scraping.
Implementación de proxies en Playwright:
async def scrape_with_proxy():
async with async_playwright() as p:
browser = await p.chromium.launch(
headless=False,
proxy={"server": "http://your-proxy-server:port"}
)
page = await browser.new_page()
await page.goto("https://www.instagram.com/profile name/", wait_until="networkidle")
# Continúe raspando como antes...
Playwright también soporta proxy para ser pasado como nombre de usuario contraseña y servidor ejemplo se da a continuación.
async def scrape_with_proxy():
async with async_playwright() as p:
browser = await p.chromium.launch(
headless=False,
proxy={"server": "http://your-proxy-server:port", "username": "username", "password": "password"}
)
page = await browser.new_page()
await page.goto("https://www.instagram.com/profile name/", wait_until="networkidle")
# Continúe raspando como antes...
Los proxies ayudan a evitar las prohibiciones de IP, los desafíos CAPTCHA y garantizan un raspado sin problemas de sitios web con muchos datos o restringidos, como Instagram.
import asyncio
from playwright.async_api import async_playwright
from lxml import html
import json
# Función para automatizar el navegador y raspar contenido dinámico con proxies
async def scrape_instagram(profile_url, proxy=None):
async with async_playwright() as p:
# Configurar el navegador con proxy si se proporciona
browser_options = {
'headless': True, # Utilizar el navegador encabezado para ver la acción (puede establecerse en True para el modo headless)
}
if proxy:
browser_options['proxy'] = proxy
# Iniciar el navegador
browser = await p.chromium.launch(**browser_options)
page = await browser.new_page()
# Visite la página del perfil de Instagram
await page.goto(profile_url, wait_until="networkidle")
# Pruebe a hacer clic en el botón "Mostrar más mensajes" (opcional, puede fallar si no se encuentra el botón)
try:
await page.click('button:has-text("Show more posts from")')
except Exception as e:
print(f"No 'Show more posts' button found: {e}")
# Desplaza la página para cargar más entradas
scroll_count = 5 # Número de desplazamientos para cargar los mensajes
for _ in range(scroll_count):
await page.evaluate('window.scrollBy(0, 500);')
await page.wait_for_timeout(3000) # Esperar a que se carguen los nuevos mensajes
await page.wait_for_load_state("networkidle")
# Obtener el contenido completo de la página después de desplazarse
content = await page.content()
await browser.close() # Cierre el navegador cuando haya terminado
return content
# Función para analizar el contenido de la página y extraer las direcciones URL de los mensajes.
def extract_post_urls(page_content):
# Analiza el contenido HTML con lxml
tree = html.fromstring(page_content)
# XPath para extraer las URL de las entradas
post_urls_xpath = '//a[contains(@href, "/p/")]/@href'
# Extraer las URL de las entradas utilizando XPath
post_urls = tree.xpath(post_urls_xpath)
# Convertir URL relativas en absolutas
base_url = "https://www.instagram.com"
post_urls = [f"{base_url}{url}" for url in post_urls]
return post_urls
# Función para guardar las URLs extraídas en un archivo JSON
def save_data(profile_url, post_urls):
# Estructurar los datos en formato JSON
data = {profile_url: post_urls}
# Save the data to a file
with open('instagram_posts.json', 'w') as json_file:
json.dump(data, json_file, indent=4)
print(f"Data saved to instagram_posts.json")
# Función principal para ejecutar el rascador y guardar los datos
async def main():
# Definir la URL del perfil de Instagram
profile_url = "https://www.instagram.com/profile name/"
# Opcionalmente, configure un proxy
proxy = {"server": "server", "username": "username", "password": "password"} # Utilice Ninguno si no necesita un proxy
# Rastrea la página de Instagram con proxies
page_content = await scrape_instagram(profile_url, proxy=proxy)
# Extraer las URL de las entradas del contenido de la página recuperada
post_urls = extract_post_urls(page_content)
# Guarda las URLs extraídas en un archivo JSON
save_data(profile_url, post_urls)
if __name__ == '__main__':
asyncio.run(main())
Aunque Playwright es una excelente opción para el scraping de sitios web dinámicos, otras herramientas podrían ser adecuadas para diferentes escenarios:
Cada herramienta ofrece puntos fuertes únicos y se puede elegir en función de las necesidades y condiciones específicas del proyecto.
Para realizar con éxito el scraping de sitios web dinámicos que utilizan activamente JavaScript y solicitudes AJAX, se necesitan herramientas potentes capaces de gestionar con eficacia el desplazamiento infinito y los elementos interactivos complejos. Una de estas soluciones es Playwright, una herramienta de Microsoft que proporciona una automatización completa del navegador, lo que la convierte en una opción ideal para plataformas como Instagram. Combinado con la biblioteca lxml para el análisis sintáctico de HTML, Playwright simplifica enormemente la extracción de datos, lo que permite automatizar las interacciones con los elementos de la página y el proceso de análisis sintáctico sin intervención manual. Además, el uso de servidores proxy ayuda a eludir la protección anti-bot y evita el bloqueo de IP, garantizando operaciones de scraping estables e ininterrumpidas.
Мы получили вашу заявку!
Ответ будет отправлен на почту в ближайшее время.
С уважением proxy-seller.ru!
Comentarios: 0