C#Web解析冲突

C#Web解析冲突,c#,.net,httpwebrequest,browser,C#,.net,Httpwebrequest,Browser,在解析一些HTML的简单尝试中,我似乎遇到了不少问题。作为实践,我正在编写一个多线程网络爬虫程序,它以要爬网的站点列表开始。这是通过几个类传递下来的,这些类最终应该会将网站的内容返回到我的系统中。这似乎相当简单,但我在以下任务中都没有运气: A.使用HtmlDocument.Write()方法将网站内容(以字符串格式,从HttpWebRequest流)转换为HtmlDocument(无法创建HtmlDocument的新实例?没有多大意义…) 或 B.通过WebBrowser实例收集HtmlDoc

在解析一些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);
            }
        }
    }
public void Start()
{
if(this.RunningThread==null)
{
Console.WriteLine(“为“+SiteRoot.DnsSafeHost”执行SiteCrawler);
this.RunningThread=新线程(this.Start);
this.RunningThread.SetApartmentState(ApartmentState.STA);
this.RunningThread.Start();
}
其他的
{
尝试
{
WebBrowser BrowserEmulator=新建WebBrowser();
BrowserEmulator.Navigate(this.SiteRoot);
HtmlElementCollection LinkCollection=BrowserEmulator.Document.GetElementsByTagName(“a”);
List PageCrawlList=新列表();
foreach(LinkCollection中的HtmleElement链接)
{
添加(新的页面爬虫程序(Link.GetAttribute(“href”),true));
继续;
}
返回;
}
捕获(例外e)
{
抛出新异常(“SiteCrawler中遇到异常:+e.Message”);
}
}
}
这段代码在通过“导航”方法时似乎什么都不做。我尝试允许它在一个新窗口中打开,该窗口弹出一个新的IE实例,并继续导航到指定的地址,但不是在我的程序跳过导航方法之前。我试着等待浏览器“不忙”,但它似乎从来没有拿起忙属性无论如何。我已经尝试通过Browser.document.OpenNew()创建一个新文档,这样我就可以用WebRequest流中的数据来填充它,但是我确信当我尝试访问该语句的“document”部分时,您可以假设我返回了一个空指针异常。我做了一些研究,这似乎是创建新HtmlDocument的唯一方法

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


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

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

如果在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);
        }
    }
}
private void OnDocCompleted(对象发送方,WebBrowserDocumentCompletedEventArgs e)
{
WebBrowser wb=发件人作为WebBrowser;
如果(wb.Document!=null)
{
列表链接=新列表();
foreach(wb.Document.GetElementsByTagName(“a”)中的HtmlElement元素)
{
links.Add(element.GetAttribute(“href”);
}
foreach(链接中的字符串链接)
{
控制台写入线(链接);
}
}
}
如果要在控制台应用程序中运行此功能,则需要使用不同的方法下载页面。我建议您使用/然后使用解析HTML。
HtmlAgilityPack
将为您生成一个
HtmlDocument
,您可以从那里获得链接


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


祝你好运

当我试着测试你的代码时,我得到了关于
这个的编译器错误。RunningThread
这个。SiteRoot
PageCrawler
等等。我想你期望的是猜测而不是真正的答案。正直的人,谢谢你的建议,我必须去拿敏捷包,我只是想把一个代码样本和我的简历一起发送到几个地方,爬虫似乎是一个相当简单、包罗万象的解决方案。@digitaljed805如果你对答案感到满意,那么请确保通过勾选答案旁边的复选标记来奖励获奖者。谢谢!:)