【问题标题】:C#.net Use HTMLDocument from Console?C#.net 从控制台使用 HTMLDocument?
【发布时间】:2009-11-22 04:21:47
【问题描述】:

我正在尝试在控制台应用程序中使用System.Windows.Forms.HTMLDocument。首先,这可能吗?如果是这样,我如何将网页从网络加载到其中?我试图使用WebBrowser,但它告诉我:

未处理的异常: System.Threading.ThreadStateException: ActiveX 控件'885 6f961-340a-11d0-a96b-00c04fd705a2' 无法实例化,因为 当前读取不在 单线程单元。

似乎严重缺乏关于 HTMLDocument 对象的教程(或者 Google 只是发现了无用的结果)。


刚刚发现mshtml.HTMLDocument.createDocumentFromUrl,但这让我很震惊

未处理的异常: System.Runtime.InteropServices.COMException (0x80010105): 服务器抛出了一个 例外。 (HRESULT 的例外情况: 0x80010105 (RPC_E_SERVERF AULT)) 在 System.RuntimeType.ForwardCallToInvokeMember(字符串 memberName,BindingFla gs 标志, 对象目标,Int32[] aWrapperTypes, 消息数据和消息数据)在 mshtml.HTMLDocumentClass.createDocumentFromUrl(字符串 bstrUrl,字符串 bstr 选项)在 iget.Program.Main(String[] args)

什么鬼?我想要的只是页面上的<a> 标签列表。为什么这么难?


对于那些好奇的人,这是我想出的解决方案,感谢TrueWill

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using HtmlAgilityPack;

namespace iget
{
    class Program
    {
        static void Main(string[] args)
        {
            WebClient wc = new WebClient();
            HtmlDocument doc = new HtmlDocument();
            doc.Load(wc.OpenRead("http://google.com"));
            foreach(HtmlNode a in doc.DocumentNode.SelectNodes("//a[@href]"))
            {
                Console.WriteLine(a.Attributes["href"].Value);
            }
        }
    }
}

【问题讨论】:

    标签: c# .net console


    【解决方案1】:

    作为替代方案,您可以使用免费的Html Agility Pack 库。它可以解析 HTML 并让您使用 LINQ 查询它。我在家里的一个项目中使用了旧版本,效果很好。

    编辑:您可能还想使用 WebClient 或 WebRequest 类来下载网页。请参阅我在 Web scraping in .NET 上的博客文章。 (请注意,我没有在控制台应用程序中尝试过。)

    【讨论】:

    • 不熟悉 LINQ,但快速浏览一下首页提到了 XPATH,这很好!如果克里斯的解决方案不起作用,可能会试一试。
    • @Mark:您不必使用 LINQ - 当我使用该库时,尚未添加该功能。这仍然很容易。您可以创建一个 XPathNavigator,在其上调用 Select 并传入一个 XPath 字符串,然后遍历结果。 SelectSingleNode 是我使用的另一个主要方法。
    • 我在我的问题中添加了一些代码。在控制台中效果很好:)
    • @Mark:谢谢!您的代码非常简洁。顺便说一句:它可能与您的程序无关,但 WebClient 是 IDisposable。
    【解决方案2】:

    将 [STAThread] 属性添加到 Main 方法中

        [STAThread]
        static void Main(string[] args)
        {
        }
    

    这应该可以解决它。

    【讨论】:

    • 我认为它不能解决问题。我创建了一个 WebBrowser 对象,然后我将 Navigategoogle.com.. 我附加了一个 DocumentCompleted 事件处理程序,所以我知道它何时完成加载,但它永远不会被触发。事实上,程序几乎立即运行完成,这告诉我它根本没有等待页面加载。我不认为它喜欢单线程。
    • 看起来您还需要一个消息泵。见stackoverflow.com/questions/764869/c-console-app-event-handling
    • 这听起来很糟糕。只是为了从网络上阅读 HTML 文档,工作量太大了 :) 不过谢谢。
    • mshtml 绝对不是为控制台使用而设计的。出于同样的原因,长期以来一直建议不要在服务器端应用程序中使用它。不过,HTML 敏捷包是解析的绝佳选择。
    【解决方案3】:

    如果是 xhtml 将其加载到 XDocument 中并解析出锚标记,或者如果您只需要锚标记,也可以使用 RegEx 来完成。

    【讨论】:

    • 这不是 XHTML。 RegEx 是一个黑客......我不知道我将使用的 HTML 格式有多么错误。我需要锚点中的链接(hrefs)。
    • 为什么正则表达式是一个黑客?也很容易获得href。 +正则表达式很快。
    • 至于为什么正则表达式(在这种情况下)是一个黑客,请参阅codinghorror.com/blog/archives/001311.html
    猜你喜欢
    • 2011-06-03
    • 1970-01-01
    • 2010-09-16
    • 2011-03-14
    • 1970-01-01
    • 1970-01-01
    • 2010-11-05
    相关资源
    最近更新 更多