2012-11-07 16 views
6

Obecnie pracuję na skrobak napisany w C# 4.0. Używam różnych narzędzi, w tym wbudowanych funkcji WebClient i RegEx .NET. Dla części mojego skrobaka parsuję dokument HTML używając HtmlAgilityPack. Mam wszystko do pracy tak, jak chciałem i przeszedłem trochę oczyszczenia kodu.KeyNotFoundException za pomocą metody HtmlEntity.DeEntitize()

Używam metody HtmlEntity.DeEntitize() do czyszczenia kodu HTML. Zrobiłem kilka testów i metoda wydawała się działać świetnie. Ale kiedy zaimplementowałem metodę w moim kodzie, ciągle otrzymywałem KeyNotFoundException. Nie ma dalszych szczegółów, więc jestem całkiem zgubiony. Mój kod wygląda następująco:

WebClient client = new WebClient(); 
string html = HtmlEntity.DeEntitize(client.DownloadString(path)); 
HtmlDocument doc = new HtmlDocument(); 
doc.LoadHtml(html); 

Pobrany HTML jest kodowany w UTF-8. Jak mogę obejść wyjątek KeyNotFound?

Odpowiedz

3

Rozumiem, że przyczyną problemu są nietypowe znaki. Załóżmy na przykład, chiński, japoński itp

Po dowiedzieć się, że to, co bohaterowie są przyczyną problemu, być może można wyszukać odpowiedniego patcha do htmlagilitypack here

To może być pomocne dla Ciebie w w przypadku, gdy chcesz samodzielnie zmodyfikować model htmlagilitypack source.

3

Cztery lata później i mam ten sam problem z niektórymi kodowanymi znakami (wersja 1.4.9.5). W moim przypadku, jest ograniczony zestaw znaków, które może wygenerować ten problem, więc ja właśnie stworzyliśmy funkcję do wykonywania zastępstwa:

// to be called before HtmlEntity.DeEntitize 
public static string ReplaceProblematicHtmlEntities(string str) 
{ 
    var sb = new StringBuilder(str); 
    //TODO: add other replacements, as needed 
    return sb.Replace(".", ".") 
     .Replace("ă", "ă") 
     .Replace("â", "â") 
     .ToString(); 
} 

w moim przypadku, łańcuch zawiera zarówno znaki html zakodowany i UTF -8 znaków, ale problem dotyczy tylko niektórych zakodowanych znaków.

To nie jest eleganckie rozwiązanie, ale szybkie rozwiązanie dla całego tekstu z ograniczoną (i znaną) ilością problematycznych zakodowanych znaków.

+0

Z ciekawości próbowałem te przypadki z 'HttpUtility.HtmlDecode” i to tylko obsługiwane ostatni przypadek «â» – Setsu

+0

@Setsu - Nie próbowałem każdy znak. Na podstawie mojego tekstu wejściowego (tylko w języku rumuńskim) znam zestaw problematycznych znaków i umieszczam je wszystkie w funkcji. Jednak w razie potrzeby należy się dostosować. To nie jest przyzwoite rozwiązanie, ale pozwala HtmlAgillityPack wykonać swoją magię później. – Alexei

+0

Może się mylę, ale myślę, że pomyliłeś to, co miałem na myśli z tym komentarzem. 'HttpUtility.HtmlDecode' funkcjonuje w przestrzeni nazw' System.Web' i jest dostarczany przez framework zamiast HtmlAgilityPack. Byłem tylko ciekawy, czy poradził sobie z tymi sprawami. – Setsu

2

Moje HTML miał blok tekstu tak:

... found in sections: 233.9 & 517.3; ...

Mimo rozstawu i przecinkiem, było interpretowanie & 517.3; jako znak Unicode.

Po prostu HTML Kodowanie nieprzetworzonego tekstu naprawiło problem dla mnie.

string raw = "sections: 233.9 & 517.3;"; 
// turn '&' into '&', etc, before DeEntitizing 
string encoded = System.Web.HttpUtility.HtmlEncode(raw); 
string deEntitized = HtmlEntity.DeEntitize(encoded); 
Powiązane problemy