当前位置:网站首页 > 更多 > 玩电脑 > 正文

[玩转系统] Invoke-WebRequest:使用 PowerShell 执行 HTTP 请求、下载文件、解析 Web

作者:精品下载站 日期:2024-12-14 23:28:26 浏览:14 分类:玩电脑

Invoke-WebRequest:使用 PowerShell 执行 HTTP 请求、下载文件、解析 Web


Invoke-WebRequest cmdlet 可用于直接从 PowerShell 控制台请求 HTTP/HTTPS/FTP 资源。您可以使用此命令发送 HTTP 请求(GET 和 POST)、从网站下载文件、解析 HTML 网页、执行身份验证、填写和提交 Web 表单等。在本文中,我们将介绍在 PowerShell 中使用 Invoke-WebRequest cmdlet 与 Web 服务交互的基本示例。

使用 Invoke-WebRequest Cmdlet 获取网页内容

Invoke-WebRequest cmdlet 允许您使用 GET 方法向指定网页发送 HTTP、HTTPS 或 FTP 请求,并从服务器接收响应。自 PowerShell 3.0 版本起,此 cmdlet 就可在 Windows 上使用。

Windows 中的 Invoke-WebRequest 命令有两个别名:

iwk

wget

运行以下命令:

Invoke-WebRequest -Uri "https://a-d.site"

[玩转系统] Invoke-WebRequest:使用 PowerShell 执行 HTTP 请求、下载文件、解析 Web

提示。如果您通过代理服务器连接到 Internet,则必须正确配置 PowerShell 以通过代理服务器访问 Web。如果不设置代理参数,则运行 IWK 命令时会收到错误消息:

Invoke-WebRequest:  Unable to connect to the remote server
CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand

[玩转系统] Invoke-WebRequest:使用 PowerShell 执行 HTTP 请求、下载文件、解析 Web

该命令加载页面并在 PowerShell 控制台中显示其内容。返回的响应不仅仅是页面的 HTML 代码。 Invoke-WebRequest cmdlet 返回 HtmlWebResponseObject 类型的对象。这样的对象是表单、链接、图像和 HTML 文档的其他重要元素的集合。让我们看看这个对象的所有属性:

$WebResponseObj = Invoke-WebRequest -Uri "https://a-d.site"
$WebResponseObj| Get-Member

[玩转系统] Invoke-WebRequest:使用 PowerShell 执行 HTTP 请求、下载文件、解析 Web

要获取包含在 HtmlWebResponseObject 对象中的网页的原始 HTML 代码,请运行:

$WebResponseObj.content

您可以列出 HTML 代码以及 Web 服务器返回的 HTTP 标头:

$WebResponseObj.rawcontent

[玩转系统] Invoke-WebRequest:使用 PowerShell 执行 HTTP 请求、下载文件、解析 Web

您只能检查 Web 服务器 HTTP 状态代码和 HTML 页面的 HTTP 标头:

$WebResponseObj.Headers

如您所见,服务器返回了响应200。这意味着请求已成功,Web 服务器可用且工作正常。

Key               Value
---               -----
Transfer-Encoding chunked
Connection        keep-alive
Vary              Accept-Encoding,Cookie
Cache-Control     max-age=3, must-revalidate
Content-Type      text/html; charset=UTF-8
Date              Wed, 13 Jul 2022 02:28:32 GMT
Server            nginx/1.20.2
X-Powered-By      PHP/5.6.40

获取网页的最后修改时间:

$WebResponseObj.ParsedHtml | Select lastModified

[玩转系统] Invoke-WebRequest:使用 PowerShell 执行 HTTP 请求、下载文件、解析 Web

您可以在连接到 Web 资源时指定用户代理字符串。 PowerShell 有一组内置的用户代理字符串:

invoke-webRequest -Uri $uri -userAgent ([Microsoft.PowerShell.Commands.PSUserAgent]::Chrome)

PowerShell 中可用代理的列表可以如下显示:

[Microsoft.PowerShell.Commands.PSUserAgent].GetProperties() | Select-Object Name, @{n='UserAgent';e={ [Microsoft.PowerShell.Commands.PSUserAgent]::$($_.Name) }}

[玩转系统] Invoke-WebRequest:使用 PowerShell 执行 HTTP 请求、下载文件、解析 Web

或者您可以设置自己的 UserAgent 字符串:

Invoke-WebRequest -Uri $uri -UserAgent 'MyApplication/1.1'

使用 Invoke-WebRequest 进行身份验证

某些网络资源需要身份验证才能访问。您可以通过 Invoke-WebRequest cmdlet 使用各种类型的身份验证(基本、NTLM、Kerberos、OAuth 或证书身份验证)。

要执行基本身份验证(通过以 Base64 编码的名称和密码进行身份验证),您首先需要获取用户名和密码:

$cred = Get-Credential
wget -Uri 'https://somesite.com' -Credential $cred

为了使用当前的 Windows 用户凭据执行 NTLM 或 Kerberos 身份验证,请添加 -UseDefaultCredentials 选项:

Invoke-WebRequest 'https://somesite.com' -UseDefaultCredentials

DefaultCredentials 不适用于基本身份验证。

要使用证书进行身份验证,您需要指定其指纹:

Invoke-WebRequest 'https://somesite.com' -CertificateThumbprint xxxxxxxxxxxxxxxxxxxxxxxxxxxxx

您可以在 PowerShell 脚本中使用现代 Bearer/OAuth 令牌身份验证。

  1. 首先,您需要从 REST API 提供商获取 OAuth 令牌(超出了本文的范围);

  2. 使用 ConvertTo-SecureString cmdlet 转换令牌:

    $Token = "12345678912345678901234567890" | ConvertTo-SecureString -AsPlainText -Force
  3. 现在您可以执行 OAuth 身份验证:

    $Params = @{
    Uri = "https://somesite.com"
    Authentication = "Bearer"
    Token = $Token }
    Invoke-RestMethod @Params

使用 PowerShell 解析和抓取 HTML 网页

Invoke-WebRequest cmdlet 允许您快速方便地解析任何网页的内容。处理 HTML 页面时,会创建链接、Web 表单、图像、脚本等的集合。

让我们看看如何访问网页上的特定对象。例如,我想获取目标 HTML 网页上所有传出链接(HREF 对象)的列表:

$SiteAdress = "https://a-d.site"
$HttpContent = Invoke-WebRequest -URI $SiteAdress
$HttpContent.Links | Foreach {$_.href }

[玩转系统] Invoke-WebRequest:使用 PowerShell 执行 HTTP 请求、下载文件、解析 Web

要获取链接文本本身(包含在 InnerText 元素中),可以使用以下命令:

$HttpContent.Links | fl innerText, href

您只能选择具有特定 CSS 类的链接:

$HttpContent.Links | Where-Object {$_.class -eq "page-numbers"} | fl innerText, href

或者URL地址中的特定文本:

$HttpContent.Links | Where-Object {$_.href -like "*powershell*"} | fl innerText,href

[玩转系统] Invoke-WebRequest:使用 PowerShell 执行 HTTP 请求、下载文件、解析 Web

然后显示该页面上所有图像的列表:

$Img.Images

创建这些图像的完整 URL 路径的集合:

$images = $Img.Images | select src

初始化 WebClient 类的新实例:

$wc = New-Object System.Net.WebClient

并将页面中的所有图像文件(及其原始文件名)下载到 c: oo1s\ 文件夹:

$images | foreach { $wc.DownloadFile( $_.src, ("c:\tools\"+[io.path]::GetFileName($_.src) ) ) }

[玩转系统] Invoke-WebRequest:使用 PowerShell 执行 HTTP 请求、下载文件、解析 Web

使用 Invoke-WebRequest cmdlet 的一个有趣示例可以在文章“使用 PowerShell 获取外部 IP 地址”中找到。

如何使用 PowerShell Wget (Invoke-WebRequest) 通过 HTTP/FTP 下载文件?

Invoke-WebRequest 允许您从网页或 FTP 站点下载文件(类似于 Windows 上的 Wget 或 cURL)。假设您想要使用 PowerShell 从 HTTP 下载文件。运行以下 PowerShell 命令:

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”

[玩转系统] Invoke-WebRequest:使用 PowerShell 执行 HTTP 请求、下载文件、解析 Web

该命令将从 HTTP 站点下载文件并将其保存到指定目录。

您还可以在同步模式下使用 BITS 从 Windows Web 服务器下载文件。

在使用 wget 下载文件之前,您可以获取文件的大小(以 MB 为单位):

$url = "https://download-installer.cdn.mozilla.net/pub/firefox/releases/102.0.1/win64/en-US/Firefox%20Setup%20102.0.1.exe"
(Invoke-WebRequest $url -Method Head).Headers.'Content-Length'/1Mb

[玩转系统] Invoke-WebRequest:使用 PowerShell 执行 HTTP 请求、下载文件、解析 Web

下面是一个 PowerShell 脚本示例,它将查找目标网页上 *.pdf 文件的所有链接,并将所有找到的文件从网站批量下载到您的计算机(每个 pdf 文件都以随机名称保存):

$OutDir="C:\docs\download\PDF"
$SiteAdress = "https://sometechdocs.com/pdf"
$HttpContent = Invoke-WebRequest -URI $SiteAdress
$HttpContent.Links | Where-Object {$_.href -like "*.pdf"} | %{Invoke-WebRequest -Uri $_.href -OutFile ($OutDir + $(Get-Random 200000)+".pdf")}

由于目标目录中的脚本,将下载页面中的所有 pdf 文件。每个文件都以随机名称保存。

在现代 PowerShell Core(6.1 及更高版本)中,Invoke-WebRequest cmdlet 支持恢复模式。更新您的 PowerShell Core 版本,您可以使用 Invoke-WebRequest 命令上的 -Resume 选项,在通信通道或服务器不可用时自动恢复下载文件:

Invoke-WebRequest -Uri $Uri -OutFile $OutFile -Resume

如何使用 PowerShell 填写并提交 HTML 表单?

许多网络服务需要将各种数据填写到 HTML 表单中。使用 Invoke-WebRequest,您可以访问任何 HTML 表单,填写必要的字段,并将完成的表单提交回服务器。在此示例中,我们将展示如何使用 PowerShell 通过标准 Web 表单登录 Facebook。

[玩转系统] Invoke-WebRequest:使用 PowerShell 执行 HTTP 请求、下载文件、解析 Web

使用以下命令,我们将有关连接 cookie 的信息保存在单独的会话变量中:

$fbauth = Invoke-WebRequest https://www.facebook.com/login.php -SessionVariable session

使用下一个命令,显示要填写登录 HTML 表单 (login_form) 的字段列表:

$fbauth.Forms["login_form"].Fields

将所需的值分配给所有字段:

$fbauth.Forms["login_form"].Fields["email"] = "[email protected]"
$fbauth.Forms["login_form"].Fields["pass"] = "Coo1P$wd"

ETC。

要将填写的表单提交(发送)到服务器,请调用 HTML 表单的 action 属性:

$Log = Invoke-WebRequest -method POST -URI ("https://www.facebook.com/login.php" + $fbauth.Forms["login_form"].Action) -Body $fbauth.Forms["login_form"].Fields -WebSession $session

您还可以使用 JSON 格式通过 POST 方法将数据发送到网页:

$headers = @{
'Content-Type'='application/json'
'apikey'='0987654321'
}
$jsonbody = @{
"siteUrl" ="https://somesite.com"
"email" = "[email protected]"
}
Invoke-WebRequest -Method 'Post' -Uri $url -Body ($jsonbody |ConvertTo-Json) -Headers $headers -ContentType "application/json"

Invoke-WebRequest:忽略 SSL/TLS 证书检查

另一个问题是 Invoke-WebRequest cmdlet 与 Internet Explorer 密切相关。例如,在未安装(或删除)IE 的 Windows Server Core 版本中,无法使用 Invoke-WebRequest cmdlet。

Invoke-WebRequest: The response content cannot be parsed because the Internet Explorer engine is not available, or Internet Explorer’s first-launch configuration is not complete. Specify the UseBasicParsing parameter and try again.

在这种情况下,可以使用 WebClient 类代替 Invoke-WebRequest。例如,要从指定 URL 下载文件,请使用该命令。

(New-Object -TypeName 'System.Net.WebClient').DownloadFile($Url, $FileName)

如果 HTTPS 站点上使用了无效的 SSL 证书,或者 PowerShell 不支持此类 SSL/TLS 协议,则 Invoke-WebRequest cmdlet 将断开连接。

Invoke-WebRequest : The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.
Invoke-WebRequest : The request was aborted: Could not create SSL/TLS secure channel.

[玩转系统] Invoke-WebRequest:使用 PowerShell 执行 HTTP 请求、下载文件、解析 Web

默认情况下,Windows PowerShell(在 Windows 10、Windows Server 2016 和旧版本 Windows 的早期版本中)使用旧版且不安全的 TLS 1.0 协议进行连接(请查看描述 PowerShell 模块安装错误的博客文章:安装模块:无法从 URI 下载)。

如果在 Windows 中未禁用旧版 TLS 1.0 和 TLS 1.1 协议,则必须运行以下命令才能在 PowerShell 连接中使用 TLS 1.2:

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

如果在 HTTPS 站点上使用自签名证书,Invoke-WebRequest cmdlet 将拒绝从中接收数据。要忽略(跳过)无效的 SSL 证书,请使用以下 PowerShell 代码:

add-type @"
using System.Net;
using System.Security.Cryptography.X509Certificates;
public class TrustAllCertsPolicy : ICertificatePolicy {
public bool CheckValidationResult(
ServicePoint srvPoint, X509Certificate certificate,
WebRequest request, int certificateProblem) {
return true;
}
}
"@
$AllProtocols = [System.Net.SecurityProtocolType]'Ssl3,Tls,Tls11,Tls12'
[System.Net.ServicePointManager]::SecurityProtocol = $AllProtocols
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
$result = Invoke-WebRequest -Uri "https://somesite.com"

在 PowerShell Core 中,Invoke-WebRequest cmdlet 有一个附加参数 -SkipCertificateCheck,允许您忽略无效的 SSL/TLS 证书。

Invoke-WebRequest cmdlet 的另一个显着缺点是其性能相当低。下载文件时,HTTP 流会全部缓冲到内存中,只有在完整下载完成后才会保存到磁盘。因此,当使用 Invoke-WebReques 下载大文件时,您可能会耗尽 RAM。

您需要 登录账户 后才能发表评论

取消回复欢迎 发表评论:

关灯