Cómo usar Invoke-WebRequest en PowerShell sin perder la cabeza
Si estás experimentando con PowerShell intentando extraer datos de sitios web o descargar archivos, seguro que te has topado con algunas peculiaridades. El cmdlet Invoke-WebRequest es bastante práctico: te permite extraer contenido, descargar e incluso rellenar formularios. Pero no es perfecto, sobre todo con problemas de SSL, problemas con el proxy o cuando trabajas en un servidor sin interfaz gráfica (headless) sin Internet Explorer. Así que aquí tienes un resumen, aunque práctico, de lo que funciona y lo que no, con algunos consejos para evitar las frustraciones habituales.
Cómo obtener contenido web sin dañar el navegador
Utilice el comando básico: a veces es suficiente
Si tu red funciona correctamente, deberías Invoke-WebRequest -Uri "https://woshub.com"obtener la página HTML completa. Cuando funciona, PowerShell devuelve un objeto útil que puedes examinar en busca de enlaces, imágenes y otros elementos interesantes. Pero, por supuesto, si usas un proxy o tu internet es exigente con los certificados SSL, podría rechazarlo.
Consejo profesional: En algunas configuraciones, este comando falla durante la primera ejecución o debido a problemas con el proxy. Quizás deba configurar el proxy explícitamente en PowerShell o configurar las variables de entorno correctas, como HTTP_PROXY y HTTPS_PROXY. Y sí, si recibe mensajes de error como «No se puede conectar», revise la configuración del proxy, especialmente si está en una red corporativa.
Lo que recibes a cambio
Sin embargo, la solicitud no devuelve simplemente HTML simple. Obtienes un objeto de tipo HtmlWebResponseObject. Contiene enlaces, imágenes, formularios; puedes acceder a todo esto con propiedades como .Links, .Content, etc. Si quieres el HTML sin procesar, simplemente inserta $WebResponseObj.content. Es bastante fácil, pero en un mal día, podría ser un poco lento o generar errores de SSL.
Protocolo de enlace con encabezados y agente de usuario
Algunos sitios te expulsan si no finges ser un navegador real. Para suplantar a los agentes de usuario, usa algo como:
Invoke-WebRequest -Uri $uri -UserAgent ([Microsoft. PowerShell. Commands. PSUserAgent]::Chrome)
O bien, establezca una cadena personalizada, porque, por supuesto, Windows tiene que hacer esto más complicado de lo necesario:
Invoke-WebRequest -Uri $uri -UserAgent 'MyCustomAgent/1.0'
Cómo lidiar con la autenticación: algunos sitios no son tan amigables
Credenciales básicas: es sencillo pero limitado
Si el sitio utiliza autenticación básica, puede proporcionar credenciales como estas:
$cred = Get-Credential
y luego:
Invoke-WebRequest -Uri 'https://somesite.com' -Credential $cred
Pero recuerda: esto solo funciona si el servidor acepta las credenciales proporcionadas. Además, si intentas usar NTLM o Kerberos, añade ` -UseDefaultCredentials` ; ten en cuenta que esto no siempre funciona en Basic.
Certificados y tokens OAuth: más complicados
Si el sitio necesita un certificado, especifique la huella digital:
Invoke-WebRequest -Uri 'https://somesite.com' -CertificateThumbprint 'YOUR_CERT_THUMBPRINT'
Los tokens OAuth necesitan un poco de scripting personalizado: primero se obtiene el token, se convierte en una cadena segura y luego se incluye como un token de portador:
$Token = 'your_oauth_token' | ConvertTo-SecureString -AsPlainText -Force $Headers = @{ Authorization = "Bearer $Token" } Invoke-WebRequest -Uri 'https://somesite.com' -Headers $Headers
Sí, es un poco como bailar, pero funciona una vez que le coges el ritmo.
Rastreo y análisis de HTML: Convierta PowerShell en su rastreador web
Obtenga todos los enlaces o imágenes fácilmente
Aquí es donde Invoke-WebRequest destaca si coopera. Para listar todos los enlaces de una página:
$Content = Invoke-WebRequest -Uri "https://woshub.com" $Content. Links | Select-Object href, innerText
Si desea enlaces específicos, filtre por clase o texto:
$Content. Links | Where-Object {$_.class -eq "page-numbers"} | Select-Object href, innerText
Para obtener imágenes:
$Content. Images | Select-Object src
Y si te sientes ambicioso, incluso puedes descargar imágenes en masa:
$wc = New-Object System. Net. WebClient $Content. Images | ForEach-Object { $url = $_.src $fileName = [io.path]::GetFileName($url) $wc. DownloadFile($url, "C:\\tools\$fileName") }
Descarga de archivos: no es necesario Wget, PowerShell lo tiene todo
Descarga de archivos sencilla
wget "https://download-installer.cdn.mozilla.net/pub/firefox/releases/102.0.1/win64/en-US/Firefox%20Setup%20102.0.1.exe" -outfile "C:\tools\firefox_setup.exe"
Esto descarga el archivo directamente a tu equipo. Si quieres comprobar el tamaño antes de descargarlo, puedes realizar una solicitud HEAD:
$url = "https://download-installer.cdn.mozilla.net/pub/firefox/releases/102.0.1/win64/en-US/Firefox%20Setup%20102.0.1.exe" ($headers = Invoke-WebRequest -Uri $url -Method Head).Headers['Content-Length'] / 1MB
Si desea obtener todos los archivos PDF de una página de una sola vez (y quizás guardarlos con nombres aleatorios), esto podría ayudar:
$OutDir = "C:\docs\download\PDF" $Site = "https://sometechdocs.com/pdf" $Content = Invoke-WebRequest -Uri $Site $Content. Links | Where-Object {$_.href -like "*.pdf"} | ForEach-Object { $fileName = [io.path]::GetFileName($_.href) $filePath = Join-Path $OutDir $fileName Invoke-WebRequest -Uri $_.href -OutFile $filePath }
Para archivos grandes o conexiones inestables, PowerShell 6+ admite el modo «Reanudar», por lo que no tendrá que reiniciar si la descarga falla. Solo asegúrese de tener PowerShell Core 6.1 o una versión posterior.
Cómo completar y enviar formularios con PowerShell: porque el web scraping no es solo leer
Iniciar sesión en un sitio web o completar formularios con cookies de sesión
$session = New-Object Microsoft. PowerShell. Commands. WebRequestSession $authPage = Invoke-WebRequest -Uri "https://www.facebook.com/login.php" -SessionVariable session $authPage. Forms["login_form"].Fields["email"] = "[email protected]" $authPage. Forms["login_form"].Fields["pass"] = "Coo1P$wd" $submitUrl = "https://www.facebook.com/login.php" + $authPage. Forms["login_form"].Action $loginResponse = Invoke-WebRequest -Uri $submitUrl -Method Post -Body $authPage. Forms["login_form"].Fields -WebSession $session
Esto permite iniciar sesión en sitios web, extraer datos o automatizar el envío de formularios mediante programación. No siempre es perfecto, sobre todo si el sitio utiliza medidas antibots o formularios dinámicos, pero es sorprendentemente útil.
Cómo manejar problemas de SSL/TLS: porque SSL es un fastidio
Ignorar certificados no válidos (si, por ejemplo, estás probando con un certificado autofirmado)
add-type @" using System. Net; using System. Security. Cryptography. X509Certificates; public class TrustAllCertsPolicy : ICertificatePolicy { public bool CheckValidationResult(ServicePoint srvPoint, X509Certificate cert, WebRequest req, int certProb) { return true; } } "@ [System. Net. ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy [System. Net. ServicePointManager]::SecurityProtocol = [Net. SecurityProtocolType]::Tls12 Invoke-WebRequest -Uri "https://somesite.com"
En PowerShell Core, puede usar -SkipCertificateCheck para obtener el mismo resultado. Tenga en cuenta que omitir las comprobaciones de SSL es peligroso y solo debe usarse para pruebas o tareas internas.
De forma predeterminada, Windows utiliza protocolos TLS antiguos e inseguros. Si recibe errores de conexión sobre confianza o discrepancias de protocolo, deberá habilitar TLS 1.2 explícitamente:
[Net. ServicePointManager]::SecurityProtocol = [Net. SecurityProtocolType]::Tls12
De lo contrario, PowerShell se negará a conectarse a sitios HTTPS modernos con certificados autofirmados o defectuosos, porque, por supuesto, Windows tiene que hacerlo más difícil de lo necesario.
En una palabra…
Invoke-WebRequest es potente, pero puede ser un poco quisquilloso. Créeme, configurar proxies, establecer los encabezados correctos y gestionar certificados SSL es la mitad del camino. Pero una vez que le coges el truco a sus peculiaridades, es una herramienta muy útil para automatizar tareas web directamente desde PowerShell.
Resumen
- Utilice el comando básico para comprobaciones rápidas (
Invoke-WebRequest -Uri "https://...") - Configurar servidores proxy/configuraciones si se producen errores de conexión
- Gestione los problemas de certificados SSL con políticas personalizadas o -SkipCertificateCheck
- Aproveche las propiedades del objeto para extraer enlaces o imágenes
- La automatización del llenado de formularios puede ser complicada, pero factible.
- Para descargas grandes, considere -Resume u otras técnicas optimizadas
Resumen
Esto es un poco torpe, pero es el manual para usar Invoke-WebRequest correctamente. Siempre hay algún problema: proxy, SSL o ajustes específicos del sitio. Aun así, en las manos adecuadas, permite automatizar tareas web sin necesidad de un navegador ni un wget externo. Ojalá esto ayude a alguien a ahorrarse unas horas de trabajo.