¿Siempre utilizas Python para el web scraping? Entonces, seguramente también te confundes sobre cuál es el mejor cliente HTTP entre Urllib, Urllib3 y Requests, ¿verdad?
Sí, en la programación Python, manejar solicitudes HTTP es un requisito común.
Python proporciona múltiples bibliotecas para cumplir esta función, y Urllib, Urllib3 y Requests son las 3 bibliotecas más comunes.
¿Qué tiene de especial cada una? ¿Cuál es la más adecuada para ti?
Todas tienen sus características únicas, pros y contras. ¡Comienza a leer este artículo y descúbrelo!
Biblioteca | Urllib | Urllib3 | Requests |
---|---|---|---|
Instalación Requerida | No | Sí | Sí |
Velocidad | Moderada | Rápida | Moderada |
Manejo de Respuestas | La respuesta generalmente requiere pasos de decodificación adicionales | No se requieren pasos de decodificación adicionales | No se requieren pasos de decodificación adicionales |
Pool de Conexiones | No soportado | Soportado | Soportado |
Facilidad de Uso | Más sintaxis complican la curva de aprendizaje | Fácil de usar | Fácil de usar y más amigable para principiantes |
Urllib es parte de la biblioteca estándar de Python para manejar URLs, y no necesitas instalar bibliotecas adicionales para usarla.
Cuando utilizas Urllib para enviar una solicitud, devuelve una matriz de bytes del objeto de respuesta. Sin embargo, hay que decir que su matriz de bytes devuelta requiere un paso de decodificación adicional, lo que puede ser desafiante para los principiantes.
Urllib
permite un control más fino con una interfaz de bajo nivel, pero también significa que se necesita escribir más código. Por lo tanto, los usuarios generalmente deben manejar manualmente la codificación de URL, la configuración de encabezados de solicitud y la decodificación de respuestas.
Pero ¡no te preocupes! Urllib proporciona funciones básicas de solicitud HTTP como solicitudes GET y POST, y también admite el análisis, codificación y decodificación de URL.
Pros:
Contras:
Urllib
es adecuado para tareas simples como solicitudes HTTP, especialmente cuando no deseas instalar bibliotecas de terceros.
También puede aprender y entender los principios subyacentes. Por lo tanto, los usuarios pueden usarlo para aprender y comprender la implementación subyacente de las solicitudes HTTP.
Sin embargo, debido a que Urllib carece de características avanzadas como el manejo de pool de conexiones, compresión por defecto y procesamiento JSON, es relativamente engorroso de usar, especialmente para solicitudes HTTP complejas.
Urllib3
proporciona abstracciones de alto nivel, incluyendo API de solicitud, pool de conexiones, compresión por defecto, codificación y decodificación JSON, entre otros.
¡Aplicar estas características es muy simple! Puedes personalizar solicitudes HTTP con solo unas pocas líneas de código. Urllib3
utiliza extensiones C para modificar el rendimiento. Por lo tanto, es el más rápido de los tres.
Urllib3 proporciona una interfaz más avanzada. También soporta características avanzadas como pool de conexiones, reintentos automáticos, configuración SSL y carga de archivos:
Pros:
Contras:
urllib3
(pip install urllib3
).Los usuarios pueden aplicar urllib3
para algunas solicitudes HTTP complejas, como el manejo de solicitudes concurrentes, gestión de pool de conexiones, etc.
Urllib3 también es adecuado para algunos requisitos que necesitan mayor rendimiento y estabilidad.
Requests
es una biblioteca popular para enviar solicitudes HTTP. Es conocida por su diseño de API simple y funciones poderosas, lo que la hace muy fácil de interactuar con la red.
Las solicitudes HTTP enviadas a través de requests
se vuelven muy simples e intuitivas. Además, tiene funciones integradas como manejo de cookies, sesiones, configuraciones de proxy y datos JSON, lo que asegura una experiencia amigable para el usuario.
También tiene algunas características poderosas:
requests
gracias a sus funciones integradas de codificación y decodificación JSON.Pros:
Requests
proporciona la API más simple y fácil de entender. Por lo tanto, enviar solicitudes HTTP será muy fácil.urllib3
integrado. Utiliza urllib3
en el fondo, combinando alta eficiencia y funciones avanzadas mientras oculta la complejidad.Contras:
Requests
debe instalarse con pip
(pip install requests
).Requests
es adecuado para casi todos los escenarios de solicitud HTTP, especialmente para rastreadores web y solicitudes de API. Debido a su sintaxis concisa y su documentación completa, también es particularmente adecuado para principiantes.
Según los resultados de la prueba de rendimiento, el rendimiento de estas tres bibliotecas en 100 iteraciones es el siguiente:
Urllib
es el segundo más rápido: el tiempo promedio de solicitud es de 1.18 segundos. Aunque es una implementación pura de Python, tiene un mejor rendimiento debido a su implementación subyacente.Urllib3
es el más rápido: el tiempo promedio de solicitud es de 0.33 segundos. Esto se debe a su extensión C y a una gestión eficiente de pool de conexiones.Requests
es el más lento: el tiempo promedio de solicitud es de 1.73 segundos. Pero su facilidad de uso y funciones ricas compensan la falta de rendimiento.Si prefieres depender de la menor cantidad posible de bibliotecas externas y los requisitos del proyecto son simples, puedes optar por urllib
. Forma parte de la biblioteca estándar de Python y no requiere instalación adicional.
Si necesitas funciones avanzadas y alto rendimiento y no te importa realizar algunas operaciones técnicas adicionales, urllib3
es una buena elección.
Para aquellos que buscan código mínimo y una interfaz fácil de usar, especialmente al manejar solicitudes HTTP complejas, requests
es ideal. Es la biblioteca más amigable para los usuarios y ampliamente utilizada para rastreadores web y solicitudes de API.
Muchos sitios web han integrado sistemas anti-bot para detectar y bloquear scripts automatizados como los rastreadores web. Por lo tanto, es esencial evitar estos bloqueos para acceder a los datos.
Una forma de evitar la detección es utilizar Nstbrowser para evitar el bloqueo IP. Urllib y urllib3 también tienen capacidades integradas para agregar proxies a las solicitudes HTTP.
Nstbrowser está diseñado con rotación de IP y desbloqueador web.
¡Prueba Nstbrowser gratis para evitar el bloqueo IP!
¿Tienes ideas y dudas interesantes sobre el web scraping y el Browserless?
¡Veamos qué comparten otros desarrolladores en Discord y Telegram!
Antes de comenzar, debes cumplir algunas condiciones:
A continuación se presentan los pasos específicos. Tomaremos el ejemplo de extraer el título del contenido de una página en el sitio web de Amazon.
Si necesitamos extraer el contenido del título h3 de la siguiente página web:
Deberíamos ejecutar el siguiente código:
import json
from urllib.parse import urlencode
from playwright.async_api import async_playwright
async def main():
async with async_playwright() as playwright:
config = {
"once": True,
"headless": True, # establecer modo sin cabeza
"autoClose": True,
"args": {"--disable-gpu": "", "--no-sandbox": ""}, # los argumentos del navegador deben ser un diccionario
"fingerprint": {
"name": 'amazon_scraper',
"platform": 'mac', # soporte: windows, mac, linux
"kernel": 'chromium', # solo soporte: chromium
"kernelMilestone": '120',
"hardwareConcurrency": 8,
"deviceMemory": 8,
},
}
query = {'config': json.dumps(config)}
profileUrl = f"ws://127.0.0.1:8848/ws/connect?{urlencode(query)}"
print("Profile URL: ", profileUrl)
browser = await playwright.chromium.connect_over_cdp(endpoint_url=profileUrl)
try:
page = await browser.new_page()
await page.goto("https://www.amazon.com/b/?_encoding=UTF8&node=121225791011&pd_rd_w=Uoi8X&content-id=amzn1.sym.dde8a7c4-f315-46af-87af-ab98d7f18222&pf_rd_p=dde8a7c4-f315-46af-87af-ab98d7f18222&pf_rd_r=CM6698M8C3J02BBVTVM3&pd_rd_wg=olMbe&pd_rd_r=ff5d2eaf-26db-4aa4-a4dd-e74ea389f355&ref_=pd_hp_d_atf_unk&discounts-widget=%2522%257B%255C%2522state%255C%2522%253A%257B%255C%2522refinementFilters%255C%2522%253A%257B%257D%257D%252C%255C%2522version%255C%2522%253A1%257D%2522")
await page.wait_for_selector('h3')
title = await page.inner_text('h3')
print(title)
finally:
await browser.close()
if __name__ == "__main__":
import asyncio
asyncio.run(main())
En el código anterior, realizamos principalmente los siguientes pasos:
Después de ejecutar el código anterior, finalmente notará la siguiente salida:
Paso 1. Deberíamos usar Playwright y Nstbrowser para visitar un sitio web que puede obtener la información actual del encabezado de solicitud.
import json
from urllib.parse import urlencode
from playwright.async_api import async_playwright
async def main():
async with async_playwright() as playwright:
config = {
"once": True,
"headless": True, # set headless mode
"autoClose": True,
"args": {"--disable-gpu": "", "--no-sandbox": ""}, # browser args should be a dictionary
"fingerprint": {
"name": 'amazon_scraper',
"platform": 'mac', # support: windows, mac, linux
"kernel": 'chromium', # only support: chromium
"kernelMilestone": '120',
"hardwareConcurrency": 8,
"deviceMemory": 8,
},
}
query = {'config': json.dumps(config)}
profileUrl = f"ws://127.0.0.1:8848/ws/connect?{urlencode(query)}"
print("Profile URL: ", profileUrl)
browser = await playwright.chromium.connect_over_cdp(endpoint_url=profileUrl)
try:
page = await browser.new_page()
await page.goto("https://httpbin.org/headers")
await page.wait_for_selector('pre')
content = await page.inner_text('pre')
print(content)
finally:
await browser.close()
if __name__ == "__main__":
import asyncio
asyncio.run(main())
A través del código anterior, veremos la siguiente salida:
Paso 2. Necesitamos usar Playwright para agregar información adicional del encabezado de solicitud configurando la intercepción de solicitud al crear la página:
{
'sec-ch-ua': '\'Not A(Brand\';v=\'99\', \'Google Chrome\';v=\'121\', \'Chromium\';v=\'121\'',
'accept-Language': 'zh-CN,en;q=0.9'
}
import json
from urllib.parse import urlencode
from playwright.async_api import async_playwright
extra_headers = {
'sec-ch-ua': '\'Not A(Brand\';v=\'99\', \'Google Chrome\';v=\'121\', \'Chromium\';v=\'121\'',
'accept-Language': 'en-US,en;q=0.9'
}
async def main():
async with async_playwright() as playwright:
config = {
"once": True,
"headless": True, # establecer modo sin cabeza
"autoClose": True,
"args": ["--disable-gpu", "--no-sandbox"], # los argumentos del navegador deben ser una lista
"fingerprint": {
"name": 'amazon_scraper',
"platform": 'mac', # soporte: windows, mac, linux
"kernel": 'chromium', # solo soporte: chromium
"kernelMilestone": '120',
"hardwareConcurrency": 8,
"deviceMemory": 8,
},
}
query = {'config': json.dumps(config)}
profileUrl = f"ws://127.0.0.1:8848/ws/connect?{urlencode(query)}"
print("Profile URL: ", profileUrl)
browser = await playwright.chromium.connect_over_cdp(endpoint_url=profileUrl)
try:
context = await browser.new_context()
page = await context.new_page()
# Agregar intercepción de solicitud para establecer encabezados adicionales
await page.route('**/*', lambda route, request: route.continue_(headers={**request.headers, **extra_headers}))
response = await page.goto("https://httpbin.org/headers")
print(await response.text())
finally:
await browser.close()
if __name__ == "__main__":
import asyncio
asyncio.run(main())
A través del código anterior, veremos la siguiente información devuelta, en la que se agregará la información de encabezado personalizada:
sec-ch-ua
.En resumen:
Requests
se ha convertido en la primera opción para la mayoría de los desarrolladores debido a su facilidad de uso y funcionalidad completa.Urllib3
destaca cuando se requiere rendimiento y características más avanzadas.urllib
es adecuado para proyectos con altos requisitos de dependencia.Dependiendo de tus necesidades y escenarios específicos, elegir la herramienta más adecuada te ayudará a manejar las solicitudes HTTP de manera más eficiente.