C#中的Html Agility Pack,Web Scraping和欺騙

c# html-agility-pack spoofing web-scraping

有沒有辦法欺騙來自C#代碼的Web請求,因此它看起來不像機器人或垃圾郵件到網站?我正在嘗試網絡抓取我的網站,但在一定數量的電話後不斷被阻止。我想表現得像一個真正的瀏覽器。我在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";

一般承認的答案

使用常規瀏覽器和fiddler (如果開發人員工具不能解決問題)並查看請求和響應標頭。

構建您的請求並請求標頭以匹配瀏覽器發送的內容(您可以使用幾個不同的瀏覽器來評估這是否有所不同)。

關於“在一定數量的通話後被阻止” - 限制你的通話。每x秒只撥一個電話。對網站表現得很好,它會對你表現得很好。

很有可能他們只是查看每秒IP地址的呼叫數量,如果超過閾值,IP地址就會被阻止。


熱門答案

我做了太多的網頁抓取,但是這裡有選項:我有一個默認的標題列表我添加,因為所有這些都是從瀏覽器中預期的:

        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是我的WebClient)。

作為進一步的幫助 - 這是我的webclient類,它可以保存cookie - 這也是一個巨大的幫助:

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;
        }
    }
}

這是我通常使用它。使用您可能具有的所有解析功能將靜態副本添加到基礎站點類:

    protected static CookieWebClient wc = new CookieWebClient();

並稱之為:

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;
    }

您可能崩潰的另一個主要原因是服務器正在關閉連接,因為您已經打開了很長時間的連接。您可以通過在上面的下載部分添加try catch來證明這一點,如果失敗,請重置webclient並嘗試再次下載:

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);
                            }

這樣可以隨時保存我的屁股,即使是服務器拒絕你,這也可以重新開始。 Cookie被清除,您可以自由漫遊。如果真的變得更糟 - 添加代理支持並獲得每50個請求應用的新代理。

這應該足以讓你踢自己和任何其他網站屁股。

對我說吧!




許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因