Как читать HTML как XML?

Я хочу извлечь пару ссылок из html-страницы, загруженной из Интернета, я думаю, что использование linq to XML было бы хорошим решением для моего случая.
Моя проблема в том, что я не могу создать XmlDocument из HTML. , использование Load(string url) не сработало, поэтому я загрузил html в строку, используя:

public static string readHTML(string url)
    {
        HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
        HttpWebResponse res = (HttpWebResponse)req.GetResponse();
        StreamReader sr = new StreamReader(res.GetResponseStream());

        string html = sr.ReadToEnd();
        sr.Close();
        return html;
    }

Когда я пытаюсь загрузить эту строку с помощью LoadXml (строка xml), я получаю исключение

'--' is an unexpected token. The expected token is '>'

Какой способ я должен использовать для чтения html-файла в анализируемый XML


person Ziv    schedule 29.03.2011    source источник
comment
HTML не обязательно должен быть допустимым XML. HTML основан на SGML, который сам по себе является надмножеством (разновидностью) XML. Следовательно, вам нужен специальный анализатор HTML, а не общий анализатор XML.   -  person Ondrej Tucny    schedule 29.03.2011
comment
Больше того же из ответов ниже и комментария выше. HTML не XML   -  person Kieren Johnstone    schedule 29.03.2011


Ответы (5)


HTML просто не то же самое, что XML (если только HTML не соответствует XHTML или HTML5 в режиме XML). Лучше всего использовать анализатор HTML для чтения HTML. Впоследствии вы можете преобразовать его в Linq to XML или обработать напрямую.

person Konrad Rudolph    schedule 29.03.2011

Я сам не использовал его, но предлагаю вам взглянуть на SGMLReader. Вот пример с их домашней страницы:

XmlDocument FromHtml(TextReader reader) {

    // setup SgmlReader
    Sgml.SgmlReader sgmlReader = new Sgml.SgmlReader();
    sgmlReader.DocType = "HTML";
    sgmlReader.WhitespaceHandling = WhitespaceHandling.All;
    sgmlReader.CaseFolding = Sgml.CaseFolding.ToLower;
    sgmlReader.InputStream = reader;

    // create document
    XmlDocument doc = new XmlDocument();
    doc.PreserveWhitespace = true;
    doc.XmlResolver = null;
    doc.Load(sgmlReader);
    return doc;
}
person Danko Durbić    schedule 29.03.2011
comment
+1 Я много лет пользуюсь SGMLReader (с момента его появления). Он очень надежен и может обрабатывать очень гнилой деформированный HTML. - person Michael Earls; 15.11.2016

Если вы хотите извлечь некоторые ссылки со страницы, как вы упомянули, попробуйте использовать HTML Agility Pack.

Этот код получает страницу из Интернета и извлекает все ссылки:

HtmlWeb web = new HtmlWeb();  
HtmlDocument document = web.Load("http://www.stackoverflow.com");  
HtmlNode[] links = document.DocumentNode.SelectNodes("//a").ToArray(); 

Откройте html-файл с диска и получите URL для конкретной ссылки:

HtmlDocument document2 = new HtmlDocument();  
document2.Load(@"C:\Temp\page.html")  
HtmlNode link = document2.DocumentNode.SelectSingleNode("//a[@id='myLink']");
Console.WriteLine(link.Attributes["href"].Value);
person derloopkat    schedule 25.07.2014

HTML — это не XML. HTML основан на SGML и, как таковой, не гарантирует, что разметка является правильно сформированным XML (XML является подмножеством самого SGML). Вы можете анализировать XHTML, то есть XML-совместимый HTML, только как XML. Но, конечно, это не относится к большинству веб-сайтов.

Для работы с HTML необходимо использовать парсер HTML.

person poke    schedule 29.03.2011
comment
Если бы я мог отметить два ответа, я бы отметил оба ваших ответа. - person Ziv; 29.03.2011

Если вы знаете интересующие вас узлы, я бы использовал регулярное выражение для извлечения ссылок из строки.

person Patrick    schedule 29.03.2011
comment
Регулярные выражения почти никогда не являются разумным подходом к разбору HTML или XML. - person Nic Gibson; 29.03.2011
comment
Я думал об этом, но я никогда не изучал регулярное выражение, и это слишком большая тема для такой маленькой задачи. - person Ziv; 29.03.2011