C# 动态生成站点将接受的cookie?

C# 动态生成站点将接受的cookie?,c#,.net,image,winforms,cookies,C#,.net,Image,Winforms,Cookies,我尝试了在网上找到的所有相关解决方案,但由于某种原因,它们都不起作用。这也不起作用,因为我们使用不同的方法 我使用的不是POST方法,而是GET方法,它正在请求中使用。我使用的站点不需要任何登录凭据即可获取图像。(站点拥有的大多数其他根域不需要cookie。) 下面的代码是我想让程序像基于web的版本一样获得图像的一部分,但有一些问题 之前,我尝试使用普通的网络客户端下载图像,因为它拒绝以PictureBox控件可以接受的任何方式显示。但后来我切换到HttpWebRequest 但是,我试图从中

我尝试了在网上找到的所有相关解决方案,但由于某种原因,它们都不起作用。这也不起作用,因为我们使用不同的方法

我使用的不是POST方法,而是GET方法,它正在请求中使用。我使用的站点不需要任何登录凭据即可获取图像。(站点拥有的大多数其他根域不需要cookie。)

下面的代码是我想让程序像基于web的版本一样获得图像的一部分,但有一些问题

之前,我尝试使用普通的网络客户端下载图像,因为它拒绝以PictureBox控件可以接受的任何方式显示。但后来我切换到HttpWebRequest

但是,我试图从中获取图像的站点的特定根域需要cookie

下面是一段代码片段,它基本上尝试从站点获取图像。唯一的问题是,除非您在HttpWebRequest中传递一些内容以及cookie,否则几乎不可能从站点获取图像

目前,我使用静态cookie作为临时解决方案

HttpWebRequest _request = (HttpWebRequest)HttpWebRequest.Create(_URL);
_request.Method = WebRequestMethods.Http.Get;
_request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";
_request.Headers.Set(HttpRequestHeader.AcceptEncoding, "gzip,deflate,sdch");
_request.Headers.Set(HttpRequestHeader.AcceptLanguage, "en-US,en;q=0.8");
_request.Headers.Set(HttpRequestHeader.CacheControl, "max-age=0");

_request.Host = "www.habbo" + _Country;
_request.UserAgent = "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36";

using (WebResponse _response = _request.GetResponse())
using (Stream _stream = _response.GetResponseStream())
{
    Image _image = Image.FromStream(_stream);
    _bitmap = new Bitmap(_image);
    string contentType = _response.ContentType;

    _PictureBox.Image = _bitmap;
}
让我们假设以下变量为:

_URL = "http://www.habbo.com/habbo-imaging/avatarimage?hb=img&user=aa&direction=2&head_direction=2&size=m&img_format=gif";

_Country = ".com";
我传递到HttpWebRequest的大部分内容都是通过查看Google Chrome开发工具的网络选项卡获得的

基于web的Habbo Imager版本似乎只是将人们引导到可以找到图像的页面,而他们的浏览器似乎以某种方式添加了cookie。我所做的是不同的,因为他们所做的只是显示图像所在的站点,但我想找到图像的真实位置,然后从中读取类型图像

显然,根据我从这个帖子中读到的内容,这个网站似乎需要用户“访问”他们:点击

我想知道的是,有没有更好的方法来获取服务器每次都乐意接受的有效cookie

或者我是否需要以某种方式欺骗网站,使其认为用户已访问并看到该页面,从而使他们可能返回我们可能需要的cookie,即使用户从未看到该页面

不太确定这是否意味着我需要以某种方式动态生成cookies

我也不明白如何使用C#真正创建或获取cookies(并设置存储的cookies),因此如果可能,请使用一些示例

我宁愿不使用任何第三方库,或者更改我使用过多的代码。程序也不会发送两个GET请求,只是为了能够获得一个GET请求所能得到的。因此,这是行不通的:


我正在使用.NET 4.0。

它比乍一看要复杂一点。浏览器实际上进行了两次调用。第一个返回一个html脚本,其中包含一小段javascript,执行该脚本时设置cookie并重新加载页面。在你的c#代码中,你必须模仿它

在form类中,添加一个实例变量来保存多个httpwebrequest调用中的所有cookie:

readonly CookieContainer cookiecontainer = new CookieContainer();
我创建了一个生成器方法,该方法创建HttpWebRequest并返回HttpWebResponse。将任何cookie添加到Cookiecontainer需要namevaluecollection

private HttpWebResponse Builder(string url, string host, NameValueCollection cookies)
{
    HttpWebRequest request = (HttpWebRequest) WebRequest.Create(url);
    request.Method = WebRequestMethods.Http.Get;
    request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";
    // _request.Headers.Set(HttpRequestHeader.AcceptEncoding, "gzip,deflate,sdch");
    request.Headers.Set(HttpRequestHeader.AcceptLanguage, "en-US,en;q=0.8");
    request.Headers.Set(HttpRequestHeader.CacheControl, "max-age=0");

    request.Host = host;
    request.UserAgent = "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36";

    request.CookieContainer = cookiecontainer;

    if (cookies != null)
    {
        foreach (var cookiekey in cookies.AllKeys)
        {
            request.CookieContainer.Add(
                new Cookie(
                    cookiekey, 
                    cookies[cookiekey],
                    @"/",
                    host));    
        }
    }
    return (HttpWebResponse) request.GetResponse();
}
如果传入的流是text/html contenttype,我们需要解析其内容并返回cookie名称和值。Parse方法只执行以下操作:

// find in the html and return the three parameters in a string array
// setCookie('YPF8827340282Jdskjhfiw_928937459182JAX666', '127.0.0.1', 10);
private static string[] Parse(Stream _stream, string encoding)
{
    const string setCookieCall = "setCookie('";

    // copy html as string
    var ms = new MemoryStream();
    _stream.CopyTo(ms);
    var html = Encoding.GetEncoding(encoding).GetString(ms.ToArray());

    // find setCookie call
    var findFirst = html.IndexOf(
        setCookieCall, 
        StringComparison.InvariantCultureIgnoreCase) + setCookieCall.Length;
    var last = html.IndexOf(");", findFirst, StringComparison.InvariantCulture);

    var setCookieStatmentCall = html.Substring(findFirst, last - findFirst);
    // take the parameters
    var parameters = setCookieStatmentCall.Split(new[] {','});
    for (int x = 0; x < parameters.Length; x++)
    {
        // cleanup
        parameters[x] = parameters[x].Replace("'", "").Trim();
    }
    return parameters;
}
//在html中查找并返回字符串数组中的三个参数
//setCookie('YPF8827340282Jdskjhfiw_928937459182JAX666','127.0.0.1',10);
私有静态字符串[]解析(流_流,字符串编码)
{
常量字符串setCookieCall=“setCookie(”;
//将html复制为字符串
var ms=新内存流();
_stream.CopyTo(ms);
var html=Encoding.GetEncoding(Encoding.GetString(ms.ToArray());
//查找setCookie调用
var findFirst=html.IndexOf(
setCookieCall,
StringComparison.InvariantCultureInogoreCase)+setCookieCall.Length;
var last=html.IndexOf(“);”,findFirst,StringComparison.InvariantCulture);
var setCookieStatmentCall=html.Substring(findFirst,last-findFirst);
//以参数为例
var parameters=setCookieStatmentCall.Split(新[]{',});
对于(int x=0;x
现在我们的构建块完成了,我们可以开始从Click方法调用我们的方法了。我们使用一个循环来调用构建器两次,以从给定的url获得结果。根据接收到的contenttype,我们从流中解析或创建图像

private void button1_Click(object sender, EventArgs e)
{
    var cookies = new NameValueCollection();
    for (int tries = 0; tries < 2; tries++)
    {
        using (var response = Builder(_URL, "www.habbo" + _Country, cookies))
        {
            using (var stream = response.GetResponseStream())
            {
                string contentType = response.ContentType.ToLowerInvariant();
                if (contentType.StartsWith("text/html"))
                {
                    var parameters = Parse(stream, response.CharacterSet);
                    cookies.Add(parameters[0], parameters[1]);
                }
                if (contentType.StartsWith("image"))
                {
                    pictureBox1.Image = Image.FromStream(stream);
                    break; // we're done, get out
                }
            }
        }
    }
}
private void按钮1\u单击(对象发送者,事件参数e)
{
var cookies=新的NameValueCollection();
for(int trys=0;trys<2;trys++)
{
使用(var response=Builder(_URL,“www.habbo”+_Country,cookies))
{
使用(var stream=response.GetResponseStream())
{
string contentType=response.contentType.ToLowerInvariant();
if(contentType.StartsWith(“text/html”))
{
var参数=Parse(stream,response.CharacterSet);
添加(参数[0],参数[1]);
}
if(contentType.StartsWith(“图像”))
{
pictureBox1.Image=Image.FromStream(流);
休息;//我们结束了,出去
}
}
}
}
}
告诫 此代码适用于问题中的url。我没有采取任何措施来处理其他模式和/或异常。这要由你来补充。此外,在进行此类刮取时,请确保网站所有者允许这样做。

您可以使用类似的方法来比较正常请求和您的程序正在执行的请求