C#屏幕刮ASP.NET Web窗体页 – POST请求不完全工作

前端之家收集整理的这篇文章主要介绍了C#屏幕刮ASP.NET Web窗体页 – POST请求不完全工作前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
请忍受我这个稍长的描述,但我有一个奇怪的问题,C#屏幕刮ASP.NET Web表单页面.我想要做的步骤如下:

1)通过HTTPS使用基本身份验证来保护站点,所以我需要正确登录.

2)我在页面上执行GET请求来检索__VIEWSTATE值(如果我没有设置这个东西,那么事情什么都不做)!

3)登录后,会有几个表单字段来完成,然后提交一个提交按钮,POST的形式就是服务器

4)当提交按钮被按下时,表单被POST到服务器,响应是相同的页面和表单,但现在在表单底部有一个额外的小HTML表格,需要一些数据.

我已经设法使用WebClient类对登录名和表单进行排序.我使用fiddler(和firebug)来检查在正常使用浏览器完成表单时发送的POST字段值.我可以从POST请求中成功获得响应,并显示正如预期在表单下方的数据表.然而,问题是,尽管表中填有数据,但是它填充了我不期望的数据.出现的数据是,如果我在浏览器中正常完成表单,但是将一个特定参数(下拉列表)设置为与将POST请求传递给服务器不同的值.我已经确认使用fiddler和firebug,我正在传递完全相同的POST参数,正常使用Web浏览器完成的表单发送.我现在完全坚持为什么这个参数不被服务器’考虑’?

一个区别是这个特定的控件是一个选择列表,它在更改时执行页面重新加载或“回发”.然而,除了稍后在表单中更改其他一些选择列表内容之外,这似乎并没有做任何事情.

我想我正在问有没有什么我会失踪,会导致这个?我完全把我的头发撕掉了.谁能帮忙?我已经发布了下面的代码(地址和参数被隐藏了隐私).

// a place to store the html
    string responseBody = "";

    // create out web client to handle the request
    using (WebClient webClient = new WebClient())
    {
        // space to store responses from the remote site
        byte[] responseBytes;

        // site uses basic authentication over HTTPS so we'll need to login
        CredentialCache credentials = new CredentialCache();
        credentials.Add(new Uri(Url),"Basic",new NetworkCredential(Username,Password));

        // set the credentials in the web client
        webClient.Credentials = credentials;

        // a place for __VIEWSTATE
        string viewState = "";

        // try and get __VIEWSTATE from the web site
        try
        {
            responseBytes = webClient.DownloadData(Url);
            viewState = GetHtmlInputValue(Encoding.UTF8.GetString(responseBytes),"__VIEWSTATE");
        }
        catch (Exception e)
        {
            bool cancel = false;
            ComponentMetaData.FireError(10,"Read web page data","Error whilst trying to get __VIEWSTATE from web page: " + e.Message,"",out cancel);
        }

        // add our POST parameters (don't forget the __VIEWSTATE or it won't work as its an ASP.NET web page)
        NameValueCollection requestParameters = new NameValueCollection();

        // add ASP.NET fields
        requestParameters.Add("__EVENTTARGET",__EVENTTARGET);
        requestParameters.Add("__EVENTARGUMENT",__EVENTARGUMENT);
        requestParameters.Add("__LASTFOCUS",__LASTFOCUS);

        // add __VIEWSTATE
        requestParameters.Add("__VIEWSTATE",viewState);

        // all other form parameters
        requestParameters.Add("btnSubmit",btnSubmit);      
        /* I've hidden the rest of the parameters hidden for privacy just in case */

        // see if we can connect and get data
        try
        {
            // set content type
            webClient.Headers.Clear();
            webClient.Headers.Add("Content-Type","application/x-www-form-urlencoded");                             

            // 'POST' the form data using web client and hope we get a response
            responseBytes = webClient.UploadValues(Url,"POST",requestParameters);

            // transform the response to a string
            responseBody = Encoding.UTF8.GetString(responseBytes);
        }
        catch (Exception e)
        {
            bool cancel = false;
            ComponentMetaData.FireError(10,"Error whilst trying to connect to web page: " + e.Message,out cancel);
        }
    }

请忽略“ComponentMetaData”引用,因为这是SSIS脚本源的一部分.

任何想法或帮助将不胜感激 – 欢呼声!

RE:感谢快速的回应,我可以对这些评论说的是…

有一个普通的ASP会话cookie,但cookie中没有值(当然,除了会话ID),我认为网站使用基本身份验证而不是表单身份验证我可以忽略cookie – 当我进入站点获取数据返回这是可以的.我想这是值得一试,但我不得不只是改变代码来使用WebRequest类方法

对于选择列表javascript,没有JavaScript在页面加载后更改选择列表的值.选择列表中唯一的JavaScript是一个onchange事件来做一个“回发”,只是在最后的POST中似乎更改了表单上的一些空白的其他选择列表.注意:生成POST请求时,包括所有POST参数,即使它们为空,并且还包括所有“web表单”特殊字段,如__VIEWSTATE,__EVENTTARGET等…

我不是Web表单的专家(MVC人自己),但网络形式的“引擎”还有什么期待?我已经为’application-type’的’application-x-www-form-urlencoded’发送了1个标题,但是我已经尝试过设置其他文件,例如从原始POST复制’User-Agent’头,但是最终与我从服务器得到一个500错误,不知道为什么会发生?

以下是“GetHtmlInputValue”的代码,它有点简单/基本,可以做得更好,但是:

private string GetHtmlInputValue(string html,string inputID)
    {
        string valueDelimiter = "value=\"";

        int namePosition = html.IndexOf(inputID);
        int valuePosition = html.IndexOf(valueDelimiter,namePosition);

        int startPosition = valuePosition + valueDelimiter.Length;
        int endPosition = html.IndexOf("\"",startPosition);

        return html.Substring(startPosition,endPosition - startPosition);
    }

解决方法

如果我正确理解你的意见,那么在下拉菜单中选择一个项目将导致POST被执行,并且服务器改变窗体另一部分中的可用选项.然后,服务器将在__VIEWSTATE字段值中包含下拉列表的当前值.

执行抓取时,应确保__VIEWSTATE包含所需的下拉列表值.要进一步调查,尝试从服务器decode the viewstate,并查看哪些值被发回.

原文链接:https://www.f2er.com/csharp/95519.html

猜你在找的C#相关文章