Pewnie nie raz zastanawialiście się jak szybko i bez nadmiernego wysiłku wyciągnąć informacje z dokumentu HTML. Niedomknięty znacznik czy brak apostrofów to już standard w większości stron. XHTML po części rozwiązuje niektóre problemy, ale stron w pełni walidowanych też za dużo nie uświadczymy. Mimo podobieństw większość stron HTML nie możemy traktować jak dokumentów XML. Platforma .NET nie dostarcza nam narzędzi do parsowania dokumentów HTML, pozostaje nam wiec korzystanie z zewnętrznych bibliotek.
W niniejszym wpisie chciałbym przedstawić bibliotekę którą poznałem już jakiś czas temu: Html Agility Pack, która nie raz już ułatwiła mi pracę. Główną zaletą tej biblioteki jest możliwość poruszanie sie po dokumencie HTML jak po dokumencie XML. Do wybierania elementów dokumentu mozemy uzyci języka XPath lub korzystając z LINQ (od wersji 1.4.0). Sam proces używania i posługiwania się wspomnianą biblioteką jest dość prosty i pokrótce zaprezentują go poniżej.
Oczywiście pierwszą czynnością jaką musimy wykonać aby móc korzystać z tej biblioteki jest dodanie do projektu referencji do pliku HTMLAgilityPack.dll. Po tej czynnosci mozemy korzystac z elementow jakie dostarcza nam biblioteka.
Klasą reprezentującą nasz dokument HTML jest HtmlDocument. Obiekt tej klasy tworzymy korzystając z domyślnego konstruktora.
[csharp]
WebClient client = new WebClient();
string html = client.DownloadString("http://blog.pietowski.com");
HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(html);
[/csharp]
Dokument HTML możemy wczytać korzystając z metody Load do której możemy przekazać strumień, obiekt klasy TextReader lub ścieżkę do pliku. Alternatywą jest użycie medody LoadHtml, którą wykorzystałem w powyższym przykładzie, wczytującej dokument bezpośrednio z obiektu klasy System.String. Przed wczytaniem dokumentu możemy ustawić odpowiednie opcje parsowania ustawiając odpowiednie wartości polom o nazwach w formacie: OptionsXXX.
W celu pobranie błędów parsowania korzystamy z dostępnej właściwości ParseErrors:
[csharp]
Console.WriteLine("Parse errors:");
foreach(HtmlParseError error in doc.ParseErrors)
{
Console.WriteLine(error.Reason);
}
[/csharp]
Główny węzeł dokumentu dostępny jest pod właściwością DocumentNode korzystając z tego obiektu możemy przeglądać kolejne węzły wczytanego dokumentu. W celu pobrania elementu na podstawie identyfikatora używamy metody GetElementbyId.
[csharp]
HtmlNode blogDescription = doc.GetElementbyId("blog-description");
if(blogDescription != null)
{
Console.WriteLine("Blog description: {0}",blogDescription.InnerText);
}
[/csharp]
Jeśli chcemy wyszukać konkretne węzły w naszym dokumencie możemy skorzystać z LINQ:
[csharp]
IEnumerable<HtmlNode> links = from link in doc.DocumentNode.DescendantNodes()
where link.Name == "a" && link.Attributes["href"] != null
select link;
IEnumerable<HtmlNode> links2 = doc.DocumentNode.DescendantNodes()
.Where(x=>x.Name == "a" && x.Attributes["href"] != null);
[/csharp]
lub wykorzystując język XPath:
[csharp]
HtmlNodeCollection xpathLinks =
doc.DocumentNode.SelectNodes("//a[@href]");
Console.WriteLine("Links:");
foreach(var link in links)
{
Console.WriteLine(link.Attributes["href"].Value);
}
[/csharp]
Najnowszą wersję opisywanej biblioteki można znaleźć na stronie http://htmlagilitypack.codeplex.com/
Projekt demonstrujący wykorzystanie HtmlAgilityPack można pobrać tutaj.
Of their last eight video games against AFC West opponents, the Cincinnati Bengals are 7-1 SU and ATS per the OddsShark NFL
Database.
PA
Thanks , I have recently been looking for information about this subject
for ages and yours is the greatest I’ve discovered so far.
But, what about the bottom line? Are you certain about the source?
In case you are searching for excellent restaurants, Harbor
Beach can also be regional, providing shopping
and dinner options galore.
An Oceanside Variety taping, a Diabetes Awareness
Affair, education for Cycle The Coast (sidenote: check-out our
discount for KOCT here) and the Oceanside Harbor Times Pageant!
She showed the classic signs of the infection of a a headache, aching muscles and weakness
or a lack of energy this fools people into thinking they
are coming down with the flu but soon after a high fever
followed by chills two to four days later this is then repeated most people
do survive the illness but this is after 10 to 20 days of being very
ill but you do need to spot the signs early. Some find this
to be a great way to catch up on the latest, and you can even
hear about a news story second hand, do a quick search on Google,
and end up reading about that very news story. For dual charging if you prefer one over
the other.
Admiring the time and effort you put into your blog and detailed information you
provide. It’s good to come across a blog every once in a while that
isn’t the same old rehashed material. Fantastic read! I’ve saved your site and I’m adding your RSS feeds to my Google account.
First of all I want to say awesome blog! I had a quick question that I’d like
to ask if you don’t mind. I was curious to find out how you center yourself and
clear your thoughts prior to writing. I have
had a hard time clearing my thoughts in getting my ideas out.
I truly do take pleasure in writing however it just seems like the
first 10 to 15 minutes are wasted simply just trying to figure out how to begin. Any recommendations or tips?
Many thanks!
Oceanside is actually a common location for weddings on the beach because of excellent sunsets and our fantastic temperature.
What’s up, after reading this awesome paragraph i am too glad to
share my familiarity here with friends.
IMHO you’ve got the right answer!
Sorry, but i was born and elevated in northern colorado and nearly daily we go out to backyard or get mail in our robe and do you know what?!
Great delivery. Outstanding arguments. Keep up the amazing effort.
Carlsbad Premium Outlets, that will be based about 15minutes south of Oceanside should be
visited by buyers.
It’s an remarkable post in favor of all the internet visitors;
they will get advantage from it I am sure.