Invoke-WebRequest:使用Powershell解析HTML网页

时间:2020-01-09 10:46:44  来源:igfitidea点击:

在PowerShell 3.0中,我们可以直接访问和解析Internet上的HTML网页。为此,引入了特殊的Invoke-WebRequest cmdlet。此cmdlet允许我们实现许多方案:从能够通过HTTP/HTTPS/FTP从任何网站下载文件/向任何网站上载文件的能力,到解析HTML页面,监视Web服务,填写和提交Web表单的能力。通常,新的cmdlet提供了导航HTML文档的DOM树的所有必要方法。在本文中,我们将介绍在PowerShell中使用Invoke-WebRequest cmdlet的基本示例。

提示。Invoke-WebRequest cmdlet在Windows PowerShell 3.0中可用,因此在开始之前,请确保使用的是此版本或者更新的PoSh版本。

使用Invoke-WebRequest Cmdlet

Invoke-WebRequest cmdlet(别名wget)可以发送和接收HTTP,HTTPS和FTP请求,并处理Web服务器返回的响应。收到的响应是HTML文档的表单,链接,图像和其他重要元素的集合。

运行以下命令:

Invoke-WebRequest -Uri "http://theitroad.local"

提示。如果我们通过代理服务器连接到Internet,则PoweShell cmdlet才能正常工作,请使用以下文章中的提示:PowerShell:在PowerShell cmdlet的代理后面工作,以便正常工作。

如我们所见,该cmdlet返回的不是简单的HTML代码。我们可以看到Web文档的各种属性。与大多数其他PowerShell cmdlet一样,Invoke-WebRequest cmdlet可以处理对象。 Invoke-WebRequest返回HtmlWebResponseObject类型的对象。让我们看一下该对象的所有属性:

$WebResponseObj = Invoke-WebRequest -Uri "http://theitroad.local" $WebResponseObj| Get-Member

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

$WebResponseObj.content

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

$WebResponseObj.rawcontent

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

$WebResponseObj.Headers

如我们所见,服务器已返回响应200,即。 e。请求已成功,并且Web服务器可用并且可以正常工作。

如何提取网页上的HTML链接列表?

让我们打开网站的主页,并获取其上的HTML链接列表:

$SiteAdress = "http://theitroad.local" $HttpContent = Invoke-WebRequest -URI $SiteAdress $HttpContent.Links | Foreach {$_.href }

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

$HttpContent.Links | fl innerText, href

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

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

或者网址中的特定文本:

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

使用PowerShell分析和剪贴HTML Web内容

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

让我们使用PowerShell获取网站主页的内容:

$Img = Invoke-WebRequest "http://theitroad.local/"

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

$Img.Images

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

$images = $Img.Images | select src

初始化WebClient类的新实例:

$wc = New-Object System.Net.WebClient

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

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

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

使用HTTP和Powershell下载文件

Invoke-WebRequest可以用作Windows的Wget或者cURL,并允许从网页或者ftp站点下载文件。假设我们需要使用PowerShell通过HTTP下载文件(在本例中为Mozilla Firefox的安装文件)。运行以下命令:

Invoke-WebRequest "https://download.mozilla.org/?product=firefox-34.0.5-SSL&os=win&lang=en-US” -outfile “c:\too1s\firefox setup 34.0.5.exe”

该cmdlet从指定的URL下载文件,并将其保存到名为" firefox setup 34.0.5.exe"的c:\tools \文件夹中。如果我们需要从FTP下载文件,只需将http://替换为ftp://。

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

因此,我们可以轻松地找到特定网页上符合特定条件的所有链接(链接CSS类,文件名中的分辨率,URL地址等),然后从接收到的链接中下载文件。例如,某个站点上有一堆指向PDF文档的链接。任务是将所有这些文件下载到计算机上。通过HTTP进行批量文件下载的PowerShell脚本的主干可能如下所示:

$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 6.1中,Invoke-WebRequest Commander支持恢复模式。因此,使用Invoke-WebRequest -Uri $Uri -OutFile $OutFileResume参数,可以在通道或者服务器崩溃的情况下继续下载文件。

通过PowerShell填写和提交HTML表单

许多Web服务要求将各种数据填充到HTML表单中。使用Invoke-WebRequest,我们可以访问任何HTML表单,填写必填字段,然后将填写的表单提交回服务器。在本示例中,很好地演示了如何使用PowerShell通过其标准Web表单登录Facebook。

使用以下命令,将有关连接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"

等等。

要将填充的表单提交(发送)到服务器,请调用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

Invoke-WebRequest cmdlet的缺点

Invoke-WebRequest cmdlet的显着缺点之一是相当低的性能。下载HTTP文件时,整个流将被缓冲到内存中,并且只有在完全下载完成后,它才会保存到本地驱动器中。因此,当使用Invoke-WebReques下载大文件时,可能会遇到RAM不足的情况。

另一个问题是Invoke-WebRequest cmdlet与Internet Explorer密切相关。例如,在未安装IE的Windows Server Core版本中,不能使用Invoke-WebRequest cmdlet。

如果在HTTP站点上使用了自签名证书,则Invoke-WebRequest cmdlet拒绝从该证书接收数据。要忽略无效的SSL证书,请使用以下代码:

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;
}
}
"@
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
$result = Invoke-WebRequest -Uri "https://somesite.net"