如何使用PowerShell或C#将网页保存为HTML文件?

7
我有以下的链接,当我通过Chrome打开该链接并右键点击页面,然后选择“另存为”将页面保存为HTML文件(c:\temp\cu2.html)时。

enter image description here

保存后,我可以使用HTML编辑器(比如VS2015)打开这个cu2.html文件,然后可以看到文件内部有一个标签,如下所示。

enter image description here

然而,如果我使用IE11(而不是Chrome)打开链接,然后将同一个页面保存为HTML文件,我根本找不到这个标签。实际上,从IE11保存的HTML文件与我可以用下面的PowerShell脚本提取的内容相同。
#Requires -version 4.0
$url = 'https://support.microsoft.com/en-us/help/4052574/cumulative-update-2-for-sql-server-2017';

$wr = Invoke-WebRequest $url;
$wr.RawContent.contains('<table') # returns false

$wr.RawContent | out-file -FilePath c:\temp\cu2_ps.html -Force; #same as the file saved from the webpage to html file in IE

我的问题是:

为什么在Chrome中保存的网页(以HTML文件形式)与IE中不同?

我如何使用PowerShell(或C#)将这样的网页保存为HTML文件(与Chrome中保存的文件相同)?

2个回答

9

该页面使用AngularJS和jQuery。这意味着一些内容将在文档就绪后加载。因此,当您使用Invoke-WebRequest发送请求时,您只会收到页面的原始内容。其他内容将在稍后加载。

要解决问题,您可以自动化IE以获得预期结果。等待页面准备好并稍等一段时间以运行AngularJs逻辑和下载所需内容即可。然后获取文档元素的内容:

$ie = new-object -ComObject "InternetExplorer.Application"
$url = "https://support.microsoft.com/en-us/help/4052574/cumulative-update-2-for-sql-server-2017"
$ie.silent = $true
$ie.navigate($url)
while($ie.Busy) { Start-Sleep -Milliseconds 100 }
Start-Sleep 10
$ie.Document.documentElement.innerHTML > "C:\Tempfiles\output.html"
$ie.Stop()
$ie.Quit()

真的很有效!谢谢Reza。另一方面(我知道我要求有点过分),你能否提供一个不涉及IE的解决方案,这样我就可以在没有安装IE的地方使用它(因为在我的环境中,不允许在服务器上安装IE)。但无论如何,我将您的解决方案投票为答案,并将在20小时内授予您赏金点数(因为系统目前不允许我授予您点数)。再次感谢您的大力帮助。 - jyao
如果没有浏览器,你的答案是“不行”,因为你需要一个脚本引擎和一个DOM引擎等来执行JavaScript并操作DOM。 - Reza Aghaei
但是,如果您要使用不同的Browser进行自动化,例如Chrome,您可以依靠使用CefSharp。我已经在Windows Forms中使用过它。这意味着您也可以在PowerShell中使用它。在最坏的情况下,您可以编写一个使用CefSharp的C#程序来为您完成此操作。但是,在不允许使用IE的环境中,我认为使用CefSharp有很多风险。我不是在谈论CefSharp,实际上所有其他第三方浏览器都是如此。 - Reza Aghaei
顺便说一下,我在脚本的结尾添加了 $ie.Stop()$ie.Quit()。这是一个非常重要的修改,请不要错过它。 - Reza Aghaei

1

您可以使用Selenium.WebDriverSelenium.Chrome.WebDriver包来下载并保存HTML内容:

var service = ChromeDriverService.CreateDefaultService();
service.HideCommandPromptWindow = true;
var options = new ChromeOptions();
options.AddArgument("headless");

using (var driver = new ChromeDriver(service, options))
{
    driver.Url = "https://support.microsoft.com/en-us/help/4052574/cumulative-update-2-for-sql-server-2017";
    File.WriteAllText("cu2_ps.html", driver.PageSource);
}

但这意味着您需要安装Chrome。您也可以使用IE驱动程序,但最好像另一个答案中建议的那样使用IE COM自动化。


Andrii,我在Visual Studio 2015交互窗口中运行了你的代码,结果和我在问题中得到的一样,即根本没有<table>标记。乍一看,我真的很喜欢你的解决方案,因为它不需要处理IE,所以非常干净,并且可以在没有安装IE的情况下使用。但不幸的是,这个解决方案不起作用。 - jyao
@jyao,我刚刚打开了HTML文件,但是显示404页面未找到,所以没有内容。在发布之前我应该先检查一下。让我再调查一下。 - Andrii Litvinov
@jyao,脚本必须运行才能呈现内容,这是真的。另一种解决方案是使用Selenium webdriver,但可能与使用IE COM自动化建议的方法没有太大区别。干杯。 - Andrii Litvinov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接