gpt4 book ai didi

C# 屏幕抓取 ASP.NET 网页表单页面 - POST 请求未完全正常工作

转载 作者:可可西里 更新时间:2023-11-01 08:50:01 26 4
gpt4 key购买 nike

请耐心等待这个略显冗长的描述,但我在 C# 屏幕抓取 ASP.NET Web 表单页面时遇到了一个奇怪的问题。我正在尝试执行的步骤如下:-

1) 该站点使用基于 HTTPS 的基本身份验证进行保护,因此我需要正确登录。

2)我正在页面上执行 GET 请求以检索 __VIEWSTATE 值(如果我不设置这个东西,该死的东西什么都不做!)

3)登录后,有几个表单字段要完成,然后是一个提交按钮,该按钮将表单发布到服务器

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

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

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

我想我在问还有什么我遗漏的会导致这种情况吗?我完全把我的头发撕掉了。任何人都可以帮忙吗?我已经发布了下面的代码(为了隐私,地址和参数被屏蔽了)。

    // 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, "", 0, 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, "Read web page data", "Error whilst trying to connect to web page: " + e.Message, "", 0, out cancel);
}
}

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

任何想法或帮助将不胜感激 - 干杯!

RE:感谢您的快速回复,我对这些评论只能说......

有正常的 ASP session cookie,但 cookie 中没有值(当然除了 session ID),我想因为该站点使用的是基本身份验证而不是表单例份验证,所以我可以忽略 cookie - 当我进入站点并返回数据,这没问题。我想这值得一试,但我必须更改代码以使用 WebRequest 类方法代替...

至于选择列表 javascript,没有 javascript 在页面加载后更改选择列表的值。选择列表上唯一的 javascript 是执行“回发”的 onchange 事件,它似乎只会更改表单上的一些其他选择列表,这些列表在最终 POST 中无论如何都是空的。注意我在生成 POST 请求时包括所有 POST 参数,即使它们是空的,我还包括所有“网络表单”特殊字段,如 __VIEWSTATE、__EVENTTARGET 等......

我不是 Web 表单方面的专家(我自己是 MVC 人),但是 Web 表单“引擎”还期待其他什么吗?我已经为“application/x-www-form-urlencoded”的“Content-Type”发送了 1 个 header ,但我尝试设置其他 header ,例如从原始 POST 复制“User-Agent” header ,但这最终我从服务器收到 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从服务器并查看哪些值被发回。

关于C# 屏幕抓取 ASP.NET 网页表单页面 - POST 请求未完全正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31543566/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com