8

C#コードからのWebリクエストをスプーフィングして、サイトにボットやスパムが当たっているように見えないようにする方法はありますか?ウェブサイトをウェブスクレイピングしようとしていますが、一定量の呼び出しが行われた後もブロックされ続けます。本物のブラウザのように振る舞いたい。HTMLAgilityPackのこのコードを使用しています。

 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";
4

2 に答える 2

26

私はあまりにも多くのWebスクレイピングを行っていますが、オプションは次のとおりです。これらはすべてブラウザーから期待されるため、追加するヘッダーのデフォルトリストがあります。

        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は私のWebクライアントです)。

さらなるヘルプとして-これはCookieを保存する私のwebclientクラスです-これも大規模なヘルプです:

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

クラッシュする可能性のあるもう1つの主な理由は、接続を開いている時間が長すぎるため、サーバーによって接続が閉じられていることです。上記のようにダウンロード部分の周りにtrycatchを追加することでこれを証明できます。失敗した場合は、Webクライアントをリセットして、もう一度ダウンロードしてみてください。

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

これは私のお尻を常に節約します、たとえそれがあなたを拒否したサーバーであったとしても、これは多くを再ジグすることができます。クッキーはクリアされ、あなたは再び自由に歩き回ることができます。本当に悪化した場合は、プロキシサポートを追加し、50件のリクエストごとに新しいプロキシを適用します。

それはあなたがあなた自身や他のサイトを蹴るのに十分すぎるはずです。

私を評価!

于 2012-12-23T11:47:51.270 に答える
8

通常のブラウザーとフィドラーを使用して(開発者ツールがスクラッチに対応していない場合)、要求ヘッダーと応答ヘッダーを確認します。

ブラウザが送信するものと一致するようにリクエストとリクエストヘッダーを作成します(これが違いを生むかどうかを評価するために、いくつかの異なるブラウザを使用できます)。

「一定量の通話後にブロックされる」に関しては、通話を抑制します。x秒ごとに1回だけ呼び出します。サイトに対して適切に動作し、サイトに対して適切に動作します。

1秒あたりのIPアドレスからの呼び出し数を確認するだけで、しきい値を超えるとIPアドレスがブロックされる可能性があります。

于 2012-12-22T18:15:03.913 に答える