.NET中的HttpWebRequest - 登录网页

时间:2010-10-03 19:38:24

标签: .net httpwebrequest webrequest

嗨 - 提前简单的问题!

状态

我已经走到这一步了,我已经实现了一个解决方案,我得到一个带有会话的cookie,但它仍然不起作用。在嗅探器工具中,我可以看到我的应用程序与使用真实网站时的区别:

REAL:ASPSESSIONIDSCRAASDB = EFFBFPEAKOBJGLAPNABPLLCB;传递= 15; ChatCannel = 1

计划:ASPSESSIONIDSCRAASDB = KPGBFPEAHNDLENDEOAEELMPJ

即使我已将会话存储为cookie,该程序的行为就像它没有登录一样。


我正在尝试创建一个小程序,帮助我玩一个利基互联网游戏(只是计算和东西)..

无论如何 - 我需要登录!登录系统基于会话..

所以......我试过这个:

string url = "http://server1.online-trucker.dk";

HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";

StreamWriter post = new StreamWriter(req.GetRequestStream());
post.Write("Username=MyUsername&Password=MyPassword");
post.Close();

HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
resp.GetResponseStream();
string kage = GetContentFromStream(resp.GetResponseStream()); 

有点天真,我希望“kage”应该包含点击“登录”按钮后的响应,我的小爬虫应该已经登录。

我正在玩的HTML:

       Brugernavn:
   <input type="text" name="Username" size="10" STYLE="font-size: 10px; background-color: #CCCCCC; border: 1px solid #666666;">
   Kode:<input type="password" name="Password" size="10" STYLE="font-size: 10px; background-color: #CCCCCC; border: 1px solid #666666;">
   <input type="submit" name="Logind" value="Logind" STYLE="font-size: 10px; background-color: #CCCCCC; border: 1px solid #666666;"> 

但是如果你对WebRequest有一点了解,我相信你现在会笑! : - )

我想做什么:

  • 输入用户名/密码
  • 点击“Log ind”
  • 能够使用现在活跃的会话在网站的整个域中播放

我真的希望有人会帮忙!

2 个答案:

答案 0 :(得分:2)

会话通常使用Cookie保存,因此您需要为您的请求分配一个Cookie容器,该容器可以重复使用。因此,假设您的查询参数的登录代码是正确的,以下内容可以帮助您。

var cookieJar = new CookieContainer();
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.CookieContainer = cookieJar;
//...make req...
req = (HttpWebRequest)WebRequest.Create(url); // request to the second page
req.CookieContainer = cookieJar; // pass inn the same cookie container

我已经包含了一个下载包装类,它可以跟踪cookie,支持gzip并跟踪页面的正确编码。像这样使用它:

var dl = new Downloader("Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; SLCC1; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 1.1.4322)")
var pageOne = dl.GetPage( "http://www.cnn.com/", null );
var pageTwo = dl.GetPage( "http://edition.cnn.com/2010/WORLD/europe/10/02/missing.balloonists/index.html", dl.Url);


public class Downloader
{
    static CookieContainer _cookieJar = new CookieContainer();
    private readonly string _userAgent;

    public Encoding Encoding { get; set; }
    public WebHeaderCollection Headers { get; set; }
    public Uri Url { get; set; }

    public static void ClearBag()
    {
        _cookieJar = new CookieContainer();
    }

    public Downloader(string userAgent)
    {
        Encoding = Encoding.GetEncoding("ISO-8859-1");
        _userAgent = userAgent;
    }

    public string GetPage(string url, string referer)
    {
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
        request.CookieContainer = _cookieJar;

        if (!string.IsNullOrEmpty(referer))
            request.Referer = referer;
        if (!string.IsNullOrEmpty(_userAgent))
            request.UserAgent = _userAgent;

        request.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip,deflate");
        request.Headers.Add("Cache-Control", "no-cache");

        using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
        {
            Headers = response.Headers;
            Url = response.ResponseUri;
            return ProcessContent(response);
        }
    }

    private string ProcessContent(HttpWebResponse response)
    {
        SetEncodingFromHeader(response);

        Stream s = response.GetResponseStream();
        if (response.ContentEncoding.ToLower().Contains("gzip"))
            s = new GZipStream(s, CompressionMode.Decompress);
        else if (response.ContentEncoding.ToLower().Contains("deflate"))
            s = new DeflateStream(s, CompressionMode.Decompress);  

        MemoryStream memStream = new MemoryStream();
        int bytesRead;
        byte[] buffer = new byte[0x1000];
        for (bytesRead = s.Read(buffer, 0, buffer.Length); bytesRead > 0; bytesRead = s.Read(buffer, 0, buffer.Length))
        {
            memStream.Write(buffer, 0, bytesRead);
        }
        s.Close();
        string html;
        memStream.Position = 0;
        using (StreamReader r = new StreamReader(memStream, Encoding))
        {
            html = r.ReadToEnd().Trim();
            html = CheckMetaCharSetAndReEncode(memStream, html);
        }            
        return html;
    }

    private void SetEncodingFromHeader(HttpWebResponse response)
    {
        string charset = null;
        if (string.IsNullOrEmpty(response.CharacterSet))
        {
            Match m = Regex.Match(response.ContentType, @";\s*charset\s*=\s*(?<charset>.*)", RegexOptions.IgnoreCase);
            if (m.Success)
            {
                charset = m.Groups["charset"].Value.Trim(new[] { '\'', '"' });
            }
        }
        else
        {
            charset = response.CharacterSet;
        }
        if (!string.IsNullOrEmpty(charset))
        {
            try
            {
                Encoding = Encoding.GetEncoding(charset);
            }
            catch (ArgumentException)
            {
            }
        }
    }

    private string CheckMetaCharSetAndReEncode(Stream memStream, string html)
    {
        Match m = new Regex(@"<meta\s+.*?charset\s*=\s*(?<charset>[A-Za-z0-9_-]+)", RegexOptions.Singleline | RegexOptions.IgnoreCase).Match(html);
        if (m.Success)
        {
            string charset = m.Groups["charset"].Value.ToLower();
            if ((charset == "unicode") || (charset == "utf-16"))
            {
                charset = "utf-8";
            }

            try
            {
                Encoding metaEncoding = Encoding.GetEncoding(charset);
                if (Encoding != metaEncoding)
                {
                    memStream.Position = 0L;
                    StreamReader recodeReader = new StreamReader(memStream, metaEncoding);
                    html = recodeReader.ReadToEnd().Trim();
                    recodeReader.Close();
                }
            }
            catch (ArgumentException)
            {
            }
        }
        return html;
    }
}

答案 1 :(得分:1)

很多这些网站都尽力阻止自动登录,就像你在这里尝试做的那样。您需要确保发送他们期望的确切数据。我通常这样做的一种方法是运行数据包嗅探器并检查在我以正常方式登录时来回飞行的HTTP数据包。一旦我有一个基线来处理它,只需要让代码模仿行为。

一个好的免费数据包嗅探应用程序是WireShark。 http://www.wireshark.org