Конфликт синтаксического анализа в C # - PullRequest
0 голосов
/ 19 октября 2011

Кажется, что я сталкиваюсь с довольно многими проблемами в простой попытке разобрать некоторый HTML.На практике я пишу многопоточный веб-сканер, который начинается со списка сайтов для сканирования.Это передается через несколько классов, которые в конечном итоге должны возвращать содержимое сайтов обратно в мою систему.Это кажется довольно простым, но мне не повезло ни в одной из следующих задач:

A.Преобразуйте содержимое веб-сайта (в строковом формате, из потока HttpWebRequest) в HtmlDocument (не удается создать новый экземпляр HtmlDocument? Не имеет особого смысла ...) с помощью метода HtmlDocument.Write ().

или

B.Соберите HtmlDocument через экземпляр WebBrowser.

Вот мой код, так как он существует, любой совет был бы полезен ...

    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, однако, поскольку я уверен, что вы можете предположить, что я получаю исключение Null Pointer, когда я пытаюсь связаться через«Документ» часть этого заявления.Я провел некоторое исследование, и это, кажется, единственный способ создать новый HtmlDocument.

Как вы можете видеть, этот метод предназначен для запуска PageCrawler для каждой ссылки на указанной странице.Я уверен, что смогу проанализировать HTML-код за символом, чтобы найти все ссылки после использования HttpWebRequest и сбора данных из потока, но это гораздо больше работы, чем необходимо для ее завершения.

Если у кого-нибудь есть совет, он будет очень признателен.Спасибо.

1 Ответ

1 голос
/ 19 октября 2011

Если это консольное приложение, оно не будет работать, поскольку консольное приложение не имеет обработчика сообщений (который необходим для обработки сообщений WebBrowser).

Если вы запустите это в приложении Windows Forms , то вам нужно обработать событие 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, и вы сможете получить ссылки оттуда.


Кроме того, если вы хотите узнать больше о создании масштабируемых веб-сканеров, ознакомьтесь сследующие ссылки:

Удачи!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...