如何使用C#将网页保存为文本文件以供后续解析。

3
我想用C#加载例如这个页面(链接) "http://finance.yahoo.com/q/ks?s=FORK+Key+Statistic",然后将页面保存为文本文件以备后续解析或抓取。我知道我可以在浏览器中(我的情况是Firefox)右键单击页面,然后选择“另存为...”,将其保存为文本文件。之后,我需要解析的所有文本数据都将在文本文件中。我想知道如何从C#自动化此过程。我从MSDN找到了这段代码,它可以自动打印网页:
private void PrintHelpPage()
{
    // Create a WebBrowser instance. 
    WebBrowser webBrowserForPrinting = new WebBrowser();

    // Add an event handler that prints the document after it loads.
    webBrowserForPrinting.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(PrintDocument);

    // Set the Url property to load the document.
    webBrowserForPrinting.Url = new Uri(@"\\myshare\help.html");
}

private void PrintDocument(object sender, WebBrowserDocumentCompletedEventArgs e)
{
    // Print the document now that it is fully loaded.
    ((WebBrowser)sender).Print();

    // Dispose the WebBrowser now that the task is complete. 
    ((WebBrowser)sender).Dispose();
}

这个方法基本可行,但是只能打印页面头部。有没有人知道类似于浏览器的保存或“另存为”命令的方法来实现类似的功能?我还尝试过其他选项,例如htmlAgilityPack、WebClient和htrpClient。这些方法都返回HTML源代码,而不含网页上显示的任何数据。如果我能找到如何查找网页数据元素位置ID的方法,那也可能很有用。

我最终让它工作了(参见下面的代码):

        WebBrowser browser = new WebBrowser();
        browser.ScriptErrorsSuppressed = true;
        int j = 0;
        label1.Text = j.ToString();
        label1.Refresh();
        int SleepTime = 3000;
        loadPage: browser.Navigate("http://finance.yahoo.com/q/ks?s=GBX+Key+Statistic");
        System.Threading.Thread.Sleep(SleepTime);
        MessageBox.Show("browser.Navigae OK"); //Why is MessageBox needed here???
        label1.Refresh();
        if (browser.ReadyState == WebBrowserReadyState.Complete)
        {
             // It's done!
            string path = @"C:\VS2015Projects\C#\caoStocksCS\textFiles\somefile13.txt";
            //MessageBox.Show("path OK");
            if (browser.Document.Body.Parent.InnerText != null)
            {
                File.WriteAllText(path, browser.Document.Body.Parent.InnerText, Encoding.GetEncoding(browser.Document.Encoding));
                MessageBox.Show("Success! somefile13.txt created");
            }
            else
            {
                MessageBox.Show("browser.Document.Body.Parent.InnerText=" + browser.Document.Body.Parent.InnerText);
                MessageBox.Show("Failure somefile13.txt not created");
            }
        }
        else
        {
            SleepTime += SleepTime;
            ++j;
            label1.Text = j.ToString();
            goto loadPage;
        }

但是,它并不是完全自动化的,因为需要使用MessageBox.Show("browser.Navigae OK"); //为什么需要使用MessageBox?或者在这里需要其他的消息框,否则代码会继续执行。
有人知道为什么需要使用MessageBox吗? 是否有任何方法可以在此处执行与MessageBox相同的操作而无需调用消息框?MessageBox会暂停系统直到被点击或关闭,有没有其他方法可以做到这一点而不需要使用消息框呢?

1个回答

8
你可以尝试使用WebClient.DownloadString方法。该方法会下载指定URL的代码并保存到字符串中。你可以查看MSDN https://msdn.microsoft.com/en-us/library/fhd1f0sw(v=vs.110).aspx 了解更多信息。
WebClient client = new WebClient();
string downloadString = client.DownloadString("http://finance.yahoo.com/q/ks?s=FORK+Key+Statistic");

然后,为了保存您下载的内容,您可以轻松使用File.WriteAllText。每当您有一个完整的字符串要写入文件时(如本例),使用此方法非常方便:

File.WriteAllText("C:/yourWebPAge.txt", downloadString);

请添加一些关于为什么这段代码有助于 OP 的解释。这将有助于提供未来观众可以学习的答案。有关更多信息,请参见 [answer]。 - Heretic Monkey
@MikeMcCaughan,你懂了。 - NicoRiff
我认为你的评论是针对@NicoRiff而不是我,因为我只是在要求这个答案的发布者包含更多信息,因为“试试这个”这样的答案对其他人来说并不是很有帮助。关于你的评论,当然它包含了HTML源代码,因为那是你所要求的... - Heretic Monkey
谢谢,Nicoff,但这是我之前尝试过的事情。我得到的文本文件似乎是源代码(html、aspx等),因为它以"<!DOCTYPE html><html id="atomic" class="NoJs desktop" lang="en-US"><head prefix="og: ogp.me/ns#"><script>window.performance && window.performance.mark && "开头,并不包含数值,比如"负债-权益比率"。 - KES
@MikeMcCaughan,我修改了我的评论...误认为是谁发布了答案。是的,你说得对,代码确实请求源代码,如果其中包含了那些值就可以正常工作。过去源代码中包含了这些值。我一直在研究无头浏览器。HtmlUtilityPack应该是一个无头浏览器,但到目前为止我也没有成功运行它。 - KES

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