почему HTML Agility Pack HtmlDocument.DocumentNode имеет значение null? - PullRequest
5 голосов
/ 04 февраля 2012

Я использую этот код для изменения атрибута href потока HTML.

сначала я загружаю полную HTML-страницу, используя этот код: (URL-адрес веб-страницы)

HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(URL);
HttpWebResponse myHttpWebResponse = 
                         (HttpWebResponse)myHttpWebRequest.GetResponse();

Stream s = myHttpWebResponse.GetResponseStream();

затем я обрабатываю это:

HtmlDocument doc = new HtmlDocument();

doc.Load(s);
foreach (HtmlNode link in doc.DocumentNode.SelectNodes("/a"))
{
    string att = link.Attributes["href"].Value;
    link.Attributes["href"].Value = "http://ahmadalli.somee.com/default.aspx?url=" + att;
}
doc.Save(s);

s - это поток html.

, но у меня есть исключение, которое говорит, что doc.DocumentNode равно нулю!

Я пробовал много сайтов, но doc.DocumentNode не имеет значения

Ответы [ 5 ]

7 голосов
/ 03 марта 2012

Это работает для меня.

using(WebClient client = new WebClient())
{
    client.Encoding = System.Text.Encoding.UTF8;
    var doc = new HtmlAgilityPack.HtmlDocument();
    doc.LoadHtml(client.DownloadString("http://www.google.com?q=stackoverflow"));
    foreach (var href in doc.DocumentNode.Descendants("a").Select(x => x.Attributes["href"]))
    {
        if (href == null) continue;
        href.Value = "http://ahmadalli.somee.com/default.aspx?url=" + HttpUtility.UrlEncode(href.Value);
    }
    StringWriter writer = new StringWriter();
    doc.Save(writer);
    var finalHtml = writer.ToString();
}

Также см. HttpUtility.UrlEncode, чтобы можно было правильно вернуть URL. В противном случае некоторые параметры в исходном URL могут вызвать проблемы.

Используйте HttpUtility.UrlDecode для декодирования.

0 голосов
/ 06 марта 2012

Ссылка на тег привязки - неверно экранированная строка:

...doc.DocumentNode.SelectNodes("/a")    //incorrect
...doc.DocumentNode.SelectNodes("//a")   //correct
...doc.DocumentNode.SelectNodes(@"/a")   //also correct

Исходный код не может выбрать какие-либо узлы и оценивается как ноль; это следует проверить, чтобы не допустить сбоя, скажем, документа, в котором вообще нет ссылок (хотя маловероятно, что это:)

var anchors = doc.DocumentNode.SelectNodes("//a");
if (anchors != null)
{
    foreach (HtmlNode link in anchors)
    {
        /*do stuff*/
    } 
}
0 голосов
/ 05 марта 2012

Попробуйте использовать следующий код:

HtmlDocument htmlDoc = new HtmlDocument
        {
            OptionAddDebuggingAttributes = false,
            OptionAutoCloseOnEnd = true,
            OptionFixNestedTags = true,
            OptionReadEncoding = true
        };
        try
        {
            using (Stream reader = myHttpWebResponse.GetResponseStream())
            {
                reader.Seek(0, SeekOrigin.Begin);
                htmlDoc.Load(reader, true);
            }
            HtmlNode node = htmlDoc.DocumentNode;
            if (node != null)
            {
                foreach (var href in doc.DocumentNode.Descendants("a").Select(x =>x.Attributes["href"]))
                 {
                     href.Value = "http://ahmadalli.somee.com/default.aspx?url=" +HttpUtility.UrlEncode(href.Value);
                 }
            }
        }
        catch { }

Я использую версию пакета HtmlAgility: 1.4.0

Решил вашу проблему? Если нет, пожалуйста, прокомментируйте. Остальное пометить как ответ.

0 голосов
/ 03 марта 2012
0 голосов
/ 04 февраля 2012

Попробуйте использовать //a вместо /a.

В XPath это в основном означает дать мне все ссылки в документе , в отличие от дать мне все ссылки в документе root .

Обновление:

Следующий код работает нормально:

        var myHttpWebRequest = (HttpWebRequest)WebRequest.Create("http://google.com");
        var myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();

        var s = myHttpWebResponse.GetResponseStream();

        var doc = new HtmlDocument();

        doc.Load(s);
        foreach (var link in doc.DocumentNode.SelectNodes("//a"))
        {
            var att = link.Attributes["href"].Value;
            link.Attributes["href"].Value = "http://ahmadalli.somee.com/default.aspx?url=" + att;

            Console.WriteLine(link.Attributes["href"].Value);
        }
...