De WebClient.DownloadString() retourneert de string met vreemde personages

Ik heb een probleem met sommige inhoud die we downloaden van de web voor een screen scraping tool die ik bouw.

in de code hieronder de tekenreeks geretourneerd via de web client downloaden string methode retourneert een aantal vreemde tekens voor de source te downloaden voor een aantal (niet alle) websites.

Ik heb onlangs toegevoegde http-headers, zoals hieronder. Eerder dezelfde code werd opgeroepen zonder dat de koppen in dezelfde zin. Ik heb niet geprobeerd variaties op de ‘Accept-Charset’ header, ik weet niet veel over het text encoding andere dan de basics.

De tekens of tekenreeksen die ik zie zijn:



en

Â

Deze tekens zijn niet zichtbaar wanneer u “view source” in een web browser. Wat kan de oorzaak zijn en hoe kan ik het verhelpen van het probleem?

string urlData = String.Empty;
WebClient wc = new WebClient();

//Add headers to impersonate a web browser. Some web sites 
//will not respond correctly without these headers
wc.Headers.Add("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12");
wc.Headers.Add("Accept", "*/*");
wc.Headers.Add("Accept-Language", "en-gb,en;q=0.5");
wc.Headers.Add("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7");

urlData = wc.DownloadString(uri);
  • Ik krijg de zelfde fout met een Windows-Toepassing schreef ik verklein mijn JS en CSS met behulp van C# YUI Compessor. Het gooit fouten op de bestanden die terug te komen met de exacte tekens die u hierboven vermeld. Ik geef client.Encoding = Encoding.UTF8; en nog steeds geeft funky chars… Ook ik ben bezig om erachter te komen hoe om te gaan met de fouten die door de C# YUI Compressor, zoals [FOUT] Ongeldige Syntaxis…
  • Het is een tijdje geleden dat ik voor het eerst kwam dit probleem en hebben geleerd een fir beetje over text encoding sinds. Om u te helpen, in feite wat u hoeft te doen is proberen en komen overeen met de codering in de http-headers komen met het antwoord. Vanaf daar decoderen van de byte-stream met de gedetecteerde codering. Als de codering is niet opgenomen in de headers, decoderen met UTF8, en dan op zoek naar een codering in het HTML-document. Als er nog niet één in de HTML-document, worden alleen links met heuristieken. Ik heb gelezen over verschillende mechanismen, maar geen gemakkelijke oplossing.
  • Ik zal na een aantal code hier de volgende keer als ik de kans krijg.
  • In mijn geval worden de gegevens geretourneerd, is gzipped en moest worden gedecomprimeerd eerste, dus ik vond dit antwoord nuttig: stackoverflow.com/a/34418228/74585
InformationsquelleAutor gb2d | 2011-01-17



5 Replies
  1. 99

     is de windows-1252 vertegenwoordiging van de octetten EF BB BF. Dat is de UTF-8-byte-order marker, wat betekent dat uw externe web pagina is gecodeerd in UTF-8, maar je leest het alsof het windows-1252. Volgens de documenten, WebClient.DownloadString gebruikt Webclient.Codering als de codering wanneer het zet de externe bron in een string. Stel System.Text.Encoding.UTF8 en dingen moet theoretisch werk.

    • Bedankt, hoewel dit levert problemen op andere websites. Nu zie ik een diamant met een vraagteken er in. Ik denk dat ik het opgeven van een codering in de http-header, dus ik moet verwachten hetzelfde terug van de web server?
    • Ongeacht wat u hebt opgegeven in de header, web servers kunnen negeren en de terugkeer van alles zijn. Je moet bereid zijn om te gaan met het vragen om UTF-8 en Windows-coderingen.
    • Als je niet weet wat het coderen van de gegevens zal worden teruggekomen, kunt u spelen op safe en pak de raw bytes met behulp van WebClient.DownloadData.
    • dkarp – Zou het niet ik heb nog om te zetten van de byte-stream in iets begrijpelijke met behulp van een codering (die als ik het goed begrijp is er geen manier om te detecteren)?
    • Ik vond eigenlijk referentie op het internet om een bug in .netto 3.5 en vond dat er is. Dezelfde locatie met dezelfde code in .netto 4 levert niet dezelfde karakter reeks voor deze site. Ik heb geëxperimenteerd met het gebruik van webrequest in de plaats, die leiden tot verschillende resultaten, hoewel niet zeker of per se beter.
    • Afbeelding niet wordt geladen met behulp van deze. Ik ben gewoon rendring google.com. Het toont Google image leeg. Gelieve te helpen

  2. 48

    De manier WebClient.DownloadString is uitgevoerd is zeer dom. Het moet voor de tekencodering van het Content-Type kop in de reactie, maar in plaats daarvan verwacht de ontwikkelaar om te vertellen van de verwachte codering van te voren. Ik weet niet wat de ontwikkelaars van deze klasse waren het denken.

    Ik heb een extra klasse die haalt de codering naam van de Content-Type kop van de reactie:

    public static class WebUtils
    {
        public static Encoding GetEncodingFrom(
            NameValueCollection responseHeaders,
            Encoding defaultEncoding = null)
        {
            if(responseHeaders == null)
                throw new ArgumentNullException("responseHeaders");
    
            //Note that key lookup is case-insensitive
            var contentType = responseHeaders["Content-Type"];
            if(contentType == null)
                return defaultEncoding;
    
            var contentTypeParts = contentType.Split(';');
            if(contentTypeParts.Length <= 1)
                return defaultEncoding;
    
            var charsetPart =
                contentTypeParts.Skip(1).FirstOrDefault(
                    p => p.TrimStart().StartsWith("charset", StringComparison.InvariantCultureIgnoreCase));
            if(charsetPart == null)
                return defaultEncoding;
    
            var charsetPartParts = charsetPart.Split('=');
            if(charsetPartParts.Length != 2)
                return defaultEncoding;
    
            var charsetName = charsetPartParts[1].Trim();
            if(charsetName == "")
                return defaultEncoding;
    
            try
            {
                return Encoding.GetEncoding(charsetName);
            }
            catch(ArgumentException ex) 
            {
                throw new UnknownEncodingException(
                    charsetName,   
                    "The server returned data in an unknown encoding: " + charsetName, 
                    ex);
            }
        }
    }

    (UnknownEncodingException is een aangepaste uitzondering van de klasse, voel je vrij om te vervangen voor InvalidOperationException of wat anders als je wilt)

    Dan de volgende uitbreiding methode voor de WebClient klasse zal doen de truc:

    public static class WebClientExtensions
    {
        public static string DownloadStringAwareOfEncoding(this WebClient webClient, Uri uri)
        {
            var rawData = webClient.DownloadData(uri);
            var encoding = WebUtils.GetEncodingFrom(webClient.ResponseHeaders, Encoding.UTF8);
            return encoding.GetString(rawData);
        }
    }

    Dus in jouw voorbeeld zou je doen:

    urlData = wc.DownloadStringAwareOfEncoding(uri);

    …en dat is het.

    • Na 4 jaar een goed antwoord? Man, alleen vanwege die u verdient mijn stem, mooie inspanning.
    • Ik geloof dat dit niet waar is. DownloadString wordt gebruikt voor de codering van het Content-Type HTTP-header, check out de bron: referencesource.microsoft.com/#System/net/System/Net/…
    • Volgens de bron, DownloadString probeert karakter codering met behulp van Content-Type kop van de aanvraag, niet het antwoord. Dat is de reden waarom Konamiman de extensie werkt goed, terwijl DownloadString niet
    • Dank je wel ton. Het werkt als een zonnetje 🙂
  3. 14
    var client = new WebClient { Encoding = System.Text.Encoding.UTF8 };
    
    var json = client.DownloadString(url);
    • dit is de perfecte code
  4. 0

    in mijn geval , ik verwijderde ooit header betrekking tot de taal -, charset enz
    Met uitzondering van de user-agent en een koekje . het werkte..

     //try commenting
     //wc.Headers.Add("Accept-Language", "en-gb,en;q=0.5");
     //wc.Headers.Add("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
  5. 0

    Geen van hen werkte niet voor mij voor een aantal speciale websites, zoals “www.yahoo.com”. De enige manier waarop ik het oplossen van mijn probleem aan het veranderen was DownloadString te OpenRead en het gebruik van UserAgent header als voorbeeld code. Echter, een paar sites zoals “www.varzesh3.com” niet werken met een van de methoden!

    WebClient client = new WebClient()    
    client.Headers.Add(HttpRequestHeader.UserAgent, "");
    var stream = client.OpenRead("http://www.yahoo.com");
    StreamReader sr = new StreamReader(stream);
    s = sr.ReadToEnd();

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *