2

ある Web クライアントから別の Web クライアントに Cookie をコピーすることは可能でしょうか。

理由

並列 Web 要求を使用しており、新しいスレッドごとに Web クライアントの新しいインスタンスを作成します。

問題

情報は機密情報であり、投稿リクエストを使用して承認が必要であり、Cookie を保存します。したがって、基本的にこれらの新しい Web クライアント インスタンスはアクセスできません。作成されているすべての Web クライアントを承認したくないので、どうにかして 1 つの Web クライアントから別の Web クライアントに Cookie をコピーすることは可能かどうか疑問に思います。

サンプルコード

public class Scrapper
{
    CookieAwareWebClient _web = new CookieAwareWebClient();

    public Scrapper(string username, string password)
    {
        this.Authorize(username, password); // This sends correct post request and then it sets the cookie on _web
    }

    public string DowloadSomeData(int pages)
    {
        string someInformation = string.Empty;

        Parallel.For(0, pages, i =>
        {
            // Cookie is set on "_web", need to copy it to "web"
            var web = new CookieAwareWebClient(); // No authorization cookie here
            html = web.DownloadString("http://example.com/"); // Can't access this page without cookie

            someInformation += this.GetSomeInformation(html)
        });

        return someInformation;
    }
}

// This is cookie aware web client that I use
class CookieAwareWebClient : WebClient
{
    private CookieContainer cookie = new CookieContainer();

    protected override WebRequest GetWebRequest(Uri address)
    {
        WebRequest request = base.GetWebRequest(address);
        if (request is HttpWebRequest)
        {
            (request as HttpWebRequest).CookieContainer = cookie;
        }
        return request;
    }
}
4

1 に答える 1

6

CookieContainerオブジェクト間でインスタンスを共有できると思いWebClientます。CookieContainerしたがって、認証が完了したら、作成する新しいクライアントごとに同じものを再利用します。後続のリクエストでCookieContainer.

まず、CookieAwareWebClientCookie コンテナーを渡すことができるカスタム コンストラクターで変更します。また、プロパティを介してコンテナー参照を取得する方法を提供します。

class CookieAwareWebClient : WebClient
{
    private CookieContainer cookie;

    public CookieContainer Cookie { get { return cookie; } }

    public CookieAwareWebClient() {
        cookie = new CookieContainer();
    }

    public CookieAwareWebClient(CookieContainer givenContainer) {
        cookie = givenContainer;
    }
}

次に、クラスは認証後に各クライアントにScrapper独自に渡す必要があります。CookieContainer

public string DowloadSomeData(int pages)
{
    string someInformation = string.Empty;
    CookieContainer cookie = this._web.Cookie;

    Parallel.For(0, pages, i =>
    {
        // pass in the auth'ed cookie
        var web = new CookieAwareWebClient(cookie);
        html = web.DownloadString("http://example.com/");

        someInformation += this.GetSomeInformation(html)
    });

    return someInformation;
}
于 2013-03-04T22:27:37.630 に答える