Parsowanie HTML chociaż wydaje się rzeczą trywialną potrafi przysporzyć wielu problemów. Związanie jest to nie tyle ze skomplikowaniem zagadnienia co z formatem w jakim otrzymujemy dane.
Szukając tagu w wielu przykładach możemy natrafić na nie zamknięte tagi, niepoprawnie sformatowane znaczniki itp.
Jednym z lepszych parserów dostępnych w .NET jest biblioteka Html Agility Pack
http://htmlagilitypack.codeplex.com/
Do projektu bibliotekę można dodać poprzez ściągnięcie odpowiedniej dll z codeplex, bądź korzystając z NuGet-a:
PM> Install-Package HtmlAgilityPack
Po zainstalowaniu biblioteki możemy przystąpić do przetwarzania HTML:
Code:
using System;
using System.Collections.Generic;
using System.Net;
using HtmlAgilityPack;
using System.Linq;
namespace HtmlAgilityPack_Sample
{
class Program
{
private static void Main(string[] args)
{
var webClient = new WebClient();
string pageContent = webClient.DownloadString(@"http://www.onet.pl/");
var htmlDocument = new HtmlDocument();
htmlDocument.LoadHtml(pageContent);
foreach (HtmlNode link in htmlDocument.DocumentNode.SelectNodes("//a[@href]"))
{
HtmlAttribute att = link.Attributes["href"];
Console.WriteLine(att.Value);
}
foreach (var div in htmlDocument.DocumentNode.SelectNodes("//div"))
{
HtmlAttribute classAttribute = div.Attributes["class"];
if (classAttribute != null)
{
Console.WriteLine(classAttribute.Value);
}
}
}
}
}
Przykładowy kod powyżej pokazuje w jaki sposób pobrać ze strony wszystkie linki i znaczniki div. Zapytania pisane są w języku XPath.
Biblioteka jest dostępna jako opensource - możemy więc pobrać kod i dodawać nową funkcjonalność.
Na temat biblioteki można znaleźć krytyczne wypowiedzi, dotyczące m.in.:
- w przypadku gdy metoda SelectNodes() nie zwróci rezultatów, zwracany jest null co uniemożliwia użycie takiego rezultatu jako rezultatu wyrażenia np. pętli foreach
- kiedy szukamy dzieci podanego węzła, metoda SelectNode szuka od początku dokumentu (aby szukała od aktualnego węzła należy podać parametr descendant::)
Z moich testów wynika, że biblioteka dobrze radzi sobie z parsowaniem nawet bardzo kiepskiej jakości kodu HTML. Wyżej wymienione problemy można samemu poprawić (kod jest dostępny). Zachęcam do eksperymentowania i podzieleniem się uwagami na temat biblioteki.
Brak komentarzy:
Prześlij komentarz