2

我正在开发一个程序,该程序将登录网站并获取某些数据。但是,我在发布登录参数和处理 cookie 时遇到了麻烦,因为每次我看到一个页面显示“您已注销或会话已过期”。很明显,我在发布参数或处理 cookie 时做错了,但不知道是哪个。我已经为此工作了一段时间,只是无法理解为什么它不能正常工作。

void Login2(string username, string password)
    {
        string pageSource;
        string formUrl = "https://forUrl.com";
        string formParams = string.Format("login={0}&sslProt={1}&pwd={2}&gru={3}", username, "", password, "115237091");
        string cookieHeader;

        HttpWebRequest req = (HttpWebRequest)WebRequest.Create(formUrl);
        req.AllowAutoRedirect = false;
        req.ContentType = "application/x-www-form-urlencoded";
        req.Method = "POST";
        byte[] bytes = System.Text.Encoding.ASCII.GetBytes(formParams);
        req.ContentLength = bytes.Length;
        using (Stream os = req.GetRequestStream())
        {
            os.Write(bytes, 0, bytes.Length);
        }
        HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
        cookieHeader = resp.Headers["Set-cookie"];

        string getUrl = "https://Urlbehindform.com";   
        HttpWebRequest getRequest = (HttpWebRequest)WebRequest.Create(getUrl);
        getRequest.Method = "GET";
        getRequest.AllowAutoRedirect = false;
        getRequest.Headers.Add("Cookie", cookieHeader);
        HttpWebResponse getResponse = (HttpWebResponse)getRequest.GetResponse();
        using (StreamReader sr = new StreamReader(getResponse.GetResponseStream()))
        {
            pageSource = sr.ReadToEnd();
        }
        Response.Redirect(getUrl);

    }

我在执行 POST 时获取 cookie,并在执行 GET 时将其发回,但由于某种原因,这似乎不起作用。起初我以为是参数,但在使用 Tamper Data 和 Firefox 进一步查看问题后,登录参数似乎工作正常。任何帮助都会很棒,因为我已经为此工作了一段时间并且无法理解它。谢谢!

更新

在尝试了一些建议后,我仍然无法让它发挥作用。然而,在深入研究 Data Tamper 后,似乎有一个带有登录参数的 POST,然后是一个 GET 到另一个页面,最后是 GET 到登录页面之后的页面(我试图去的那个) . 经过进一步调试后,我实际上发现我的登录 POST 没有像我想象的那样工作,因为响应头位置显示“/cv/scripts/A028/eng/logErr.asp”。这意味着我的其余代码可能一直都很好,因为 POST 没有给我一个有效的登录名。关于为什么我总是得到登录错误页面的任何建议?一如既往地感谢您的帮助。

更新

在进一步使用 Tamper Data 之后,似乎我无法成功登录的原因是为了成功 POST 参数,需要已经获得 cookie。我该怎么做呢?

4

2 回答 2

2

对两个请求都使用一个CookieContainer。这样您就不必手动复制 cookie。

我 [BMW1] 添加了一个名为 cookie 的 CookieContainer,但它仍然无法正常工作,我不确定我是否以正确的方式使用 CookieContainer。这是我的代码的更新版本。

由我[Hans Kesting]编辑,见[HK]评论

    void Login2(string username, string password)
    {
        string pageSource;
        string formUrl = "https://server/cv/scripts/A028/eng/logProc.asp?ntry=0&dbg=";
        string formParams = string.Format("login={0}&sslProt={1}&pwd={2}&gru={3}", username, "", password, "115237091");

        // [HK] create a container for the cookies, where they are added automatically
        CookieContainer cookies = new CookieContainer();
        HttpWebRequest req = (HttpWebRequest)WebRequest.Create(formUrl);
        req.CookieContainer = cookies;
        req.AllowAutoRedirect = false;
        req.ContentType = "application/x-www-form-urlencoded";
        req.Method = "POST";
        byte[] bytes = System.Text.Encoding.ASCII.GetBytes(formParams);
        req.ContentLength = bytes.Length;
        using (Stream os = req.GetRequestStream())
        {
            os.Write(bytes, 0, bytes.Length);
        }
        HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
        // [HK] no need to add cookies "by hand", that will happen automatically
        //cookies.Add(resp.Cookies);


        string getUrl = "https://server/cv/scripts/A028/eng/home.asp";
        HttpWebRequest getRequest = (HttpWebRequest)WebRequest.Create(getUrl);
        // [HK] use the same cookiecontainer as on the first request - correct
        getRequest.CookieContainer = cookies; 
        getRequest.Method = "GET";
        getRequest.AllowAutoRedirect = false;
        HttpWebResponse getResponse = (HttpWebResponse)getRequest.GetResponse();
        // [HK] no need to add cookies, they should be there already
        //cookies.Add(getResponse.Cookies);
        using (StreamReader sr = new StreamReader(getResponse.GetResponseStream()))
        {
            pageSource = sr.ReadToEnd();
        }
        // [HK] no need to add cookies, they should be there already
        // cookies.Add(getResponse.Cookies);
        Response.Redirect(getUrl);

    }
于 2012-06-14T13:57:02.553 回答
0

您可以使用可识别 Cookie 的 Web 客户端,

public class CookieAwareWebClient : WebClient
{
    public CookieContainer CookieContainer { get; set; }
    public Uri Uri { get; set; }

    public CookieAwareWebClient() : this (new CookieContainer())
    {
    }

    public CookieAwareWebClient(CookieContainer cookies)
    {
        this.CookieContainer = cookies;
    }

    protected override WebRequest GetWebRequest(Uri address)
    {
        WebRequest request = base.GetWebRequest(address);
        if (request is HttpWebRequest)
    {
         (request as HttpWebRequest).CookieContainer = this.CookieContainer;
    }
    HttpWebRequest httpRequest = (HttpWebRequest) request;
    httpRequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
    return httpRequest;
    }

    protected override WebResponse GetWebResponse(WebRequest request)
    {
        WebResponse response = base.GetWebResponse(request);
    String setCookieHeader = response.Headers[HttpResponseHeader.SetCookie];

    if (setCookieHeader != null)
    {
        //do something if needed to parse out the cookie.
        if (setCookieHeader != null)
        {
            Cookie cookie = new Cookie(); //create cookie
        this.CookieContainer.Add(cookie);
        }
    }
    return response;
    }
}

示例用法:


var wc = new CookieAwareWebClient ();
wc.Headers["Content-type"] = "application/x-www-form-urlencoded";
string HtmlResult = wc.UploadString(URI, myParameters);
于 2012-06-14T13:59:12.070 回答