【问题标题】:C# Web Parsing ConflictC# Web 解析冲突
【发布时间】:2011-12-10 11:27:25
【问题描述】:

似乎我在尝试解析一些 HTML 时遇到了很多问题。作为实践,我正在编写一个多线程网络爬虫,它从要爬取的网站列表开始。这通过几个类传递下来,最终应该将站点的内容返回到我的系统。这似乎很简单,但我在以下任何一项任务中都没有运气:

A.使用 HtmlDocument.Write() 方法将网站的内容(以字符串格式,从 HttpWebRequest 流)转换为 HtmlDocument(无法创建 HtmlDocument 的新实例?没有多大意义...)。

B.通过 WebBrowser 实例收集 HtmlDocument。

这是我的代码,任何建议都会很棒...

    public void Start()
    {
        if (this.RunningThread == null)
        {
            Console.WriteLine( "Executing SiteCrawler for " + SiteRoot.DnsSafeHost);

            this.RunningThread = new Thread(this.Start);
            this.RunningThread.SetApartmentState(ApartmentState.STA);
            this.RunningThread.Start();
        }
        else
        {
            try
            {
                WebBrowser BrowserEmulator = new WebBrowser();
                BrowserEmulator.Navigate(this.SiteRoot);

                HtmlElementCollection LinkCollection = BrowserEmulator.Document.GetElementsByTagName("a");
                List<PageCrawler> PageCrawlerList = new List<PageCrawler>();

                foreach (HtmlElement Link in LinkCollection)
                {
                    PageCrawlerList.Add(new PageCrawler(Link.GetAttribute("href"), true));
                    continue;
                }
                return;
            }
            catch (Exception e)
            {
                throw new Exception("Exception encountered in SiteCrawler: " + e.Message);
            }
        }
    }

当它通过“导航”方法时,这段代码似乎什么都不做。我试图让它在一个新窗口中打开,它会弹出一个新的 IE 实例,并继续导航到指定的地址,但不是在我的程序跳过导航方法之前。我试过等待浏览器“不忙”,但它似乎永远不会拿起忙属性。我已经尝试通过 Browser.Document.OpenNew() 创建一个新文档,以便我可以使用 WebRequest 流中的数据填充它,但是我确信你可以假设我在尝试访问时返回一个空指针异常该声明的“文档”部分。我做了一些研究,这似乎是创建新 HtmlDocument 的唯一方法。

如您所见,此方法旨在为指定页面中的每个链接启动一个“PageCrawler”。我确信在使用 HttpWebRequest 并从流中收集数据之后,我可以逐个字符地解析 HTML 以找到所有链接,但这远远超出了完成此工作所需的工作量。

如果有人有任何建议,将不胜感激。谢谢。

【问题讨论】:

标签: c# .net httpwebrequest browser


【解决方案1】:

如果这是一个控制台应用程序,那么它将无法工作,因为该控制台应用程序没有消息泵(WebBrowser 处理消息所必需的)。

如果您在 Windows 窗体应用程序中运行它,那么您应该处理 DocumentCompleted 事件:

WebBrowser browserEmulator = new WebBrowser();
browserEmulator.DocumentCompleted += OnDocumentCompleted;
browserEmulator.Navigate(this.SiteRoot);

然后实现处理事件的方法:

private void OnDocCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
    WebBrowser wb = sender as WebBrowser;

    if (wb.Document != null)
    {
        List<string> links = new List<string>();

        foreach (HtmlElement element in wb.Document.GetElementsByTagName("a"))
        {
            links.Add(element.GetAttribute("href"));
        }

        foreach (string link in links)
        {
            Console.WriteLine(link);
        }
    }
}

如果您想在控制台应用程序中运行它,那么您需要使用不同的方法来下载页面。我建议您使用WebRequest/WebResponse,然后使用HtmlAgilityPack 解析HTML。 HtmlAgilityPack 将为您生成一个HtmlDocument,您可以从那里获取链接。


此外,如果您有兴趣了解有关构建可扩展网络爬虫的更多信息,请查看以下链接:

祝你好运!

【讨论】:

  • 义人,谢谢你的建议,我得去拿敏捷包,我只是想整理一个代码示例,以便与我的简历一起发送到几个地方,爬虫似乎是一个相当简单、包罗万象的解决方案。
  • @DigitalJedi805 如果您对答案感到满意,请确保您通过勾选答案旁边的复选标记来奖励获胜者。谢谢! :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-02
  • 2020-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-03
相关资源
最近更新 更多