Html Agility Pack, Web Scraping und Spoofing in C #

c# html-agility-pack spoofing web-scraping

Frage

Gibt es eine Möglichkeit, eine Web-Anfrage aus C # -Code zu spoofen, so dass es nicht aussieht, als ob ein Bot oder Spam auf die Seite gelangt? Ich versuche, meine Website zu scrappen, werde aber nach einer bestimmten Anzahl von Anrufen blockiert. Ich möchte mich wie ein echter Browser verhalten. Ich verwende diesen Code von HTML Agility Pack.

 var web = new HtmlWeb();
                web.UserAgent =
                    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.97 Safari/537.11";

Akzeptierte Antwort

Verwenden Sie einen normalen Browser und einen Fiddler (wenn die Entwickler-Tools nicht auf dem neuesten Stand sind) und werfen Sie einen Blick auf die Request- und Response-Header.

Erstellen Sie Ihre Anfragen und fordern Sie die Kopfzeilen an, damit sie mit dem übereinstimmen, was der Browser sendet (Sie können ein paar verschiedene Browser verwenden, um zu beurteilen, ob dies einen Unterschied macht).

In Bezug auf "Blockieren nach einer bestimmten Anzahl von Anrufen" - drosseln Sie Ihre Anrufe. Führen Sie nur alle x Sekunden einen Anruf durch. Benimm dich schön auf der Seite und es wird sich gut zu dir verhalten.

Die Chancen stehen gut, dass sie sich die Anzahl der Anrufe von Ihrer IP-Adresse pro Sekunde ansehen und wenn sie einen Schwellenwert überschreiten, wird die IP-Adresse blockiert.


Beliebte Antwort

Ich mache viel zu viel Web Scraping, aber hier sind die Optionen: Ich habe eine Standardliste von Headern, die ich hinzufüge, da alle diese von einem Browser erwartet werden:

        wc.Headers[HttpRequestHeader.UserAgent] = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.97 Safari/537.11";
        wc.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
        wc.Headers[HttpRequestHeader.Accept] = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
        wc.Headers[HttpRequestHeader.AcceptEncoding] = "gzip,deflate,sdch";
        wc.Headers[HttpRequestHeader.AcceptLanguage] = "en-GB,en-US;q=0.8,en;q=0.6";
        wc.Headers[HttpRequestHeader.AcceptCharset] = "ISO-8859-1,utf-8;q=0.7,*;q=0.3";

(WC ist mein WebClient).

Als weitere Hilfe - hier ist meine Webclient-Klasse, die Cookies speichert - was auch eine große Hilfe ist:

public class CookieWebClient : WebClient
{

    public CookieContainer m_container = new CookieContainer();
    public WebProxy proxy = null;

    protected override WebRequest GetWebRequest(Uri address)
    {
        try
        {
            ServicePointManager.DefaultConnectionLimit = 1000000;
            WebRequest request = base.GetWebRequest(address);
            request.Proxy = proxy;

            HttpWebRequest webRequest = request as HttpWebRequest;
            webRequest.Pipelined = true;
            webRequest.KeepAlive = true;
            if (webRequest != null)
            {
                webRequest.CookieContainer = m_container;
            }

            return request;
        }
        catch
        {
            return null;
        }
    }
}

Hier ist meine übliche Verwendung dafür. Fügen Sie Ihrer Basis-Site-Klasse eine statische Kopie mit all Ihren Analysefunktionen hinzu, die Sie wahrscheinlich haben:

    protected static CookieWebClient wc = new CookieWebClient();

Und nenne es so:

public HtmlDocument Download(string url)
    {
        HtmlDocument hdoc = new HtmlDocument();
        HtmlNode.ElementsFlags.Remove("option");
        HtmlNode.ElementsFlags.Remove("select");
        Stream read = null;
        try
        {
            read = wc.OpenRead(url);
        }
        catch (ArgumentException)
        {
            read = wc.OpenRead(HttpHelper.HTTPEncode(url));
        }

        hdoc.Load(read, true);


        return hdoc;
    }

Der andere Hauptgrund, aus dem Sie möglicherweise abstürzen, ist, dass die Verbindung vom Server geschlossen wird, da Sie zu lange eine offene Verbindung hatten. Sie können dies beweisen, indem Sie wie oben beschrieben einen Try Catch um den Download-Teil hinzufügen. Wenn dies fehlschlägt, setzen Sie den Webclient zurück und versuchen Sie es erneut:

HtmlDocument d = new HtmlDocument();
                            try
                            {
                                d = this.Download(prp.PropertyUrl);
                            }
                            catch (WebException e)
                            {
                                this.Msg(Site.ErrorSeverity.Severe, "Error connecting to " + this.URL + " : Resubmitting..");
                                wc = new CookieWebClient();
                                d = this.Download(prp.PropertyUrl);
                            }

Das rettet meinen Arsch die ganze Zeit, selbst wenn es der Server war, der dich abweist, kann das die Sache neu machen. Cookies werden gelöscht und Sie können wieder frei roamen. Wenn das Schlimmste schlimmer wird - fügen Sie Proxy-Unterstützung hinzu und lassen Sie sich einen neuen Proxy für 50-ish-Anfragen geben.

Das sollte mehr als genug für Sie sein, um Ihre eigenen und anderen Seiten Arsch zu treten.

BEWERTE MICH!



Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum