将cookie从一个WebClient复制到另一个
本文关键字:WebClient 一个 复制 另一个 cookie | 更新日期: 2023-09-27 18:02:06
我想知道是否有可能从一个web客户端复制cookie到另一个。
的原因我正在使用并行web请求,它在每个新线程上创建新的web客户端实例。
信息敏感,需要post请求授权,保存cookie。基本上这些新的web客户端实例无法访问。我不想授权每个正在创建的web客户端,所以我想知道是否有可能以某种方式将cookie从一个web客户端复制到另一个web客户端。
示例代码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;
}
}
我相信您可以在WebClient
对象之间共享CookieContainer
实例。因此,完成身份验证后,为创建的每个新客户机重用相同的CookieContainer
。只要注意您的后续请求没有修改CookieContainer
,否则您可能会有一个竞争条件,因为我怀疑该类对于并行修改是线程安全的。
首先,用一个可以传入cookie容器的自定义构造函数修改CookieAwareWebClient
。另外,提供一种通过属性获取容器引用的方法:
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;
}