我使用webbrower构建了一个C#应用程序,以便在使用https并登录的特定网站上自动保存财务活动。用户手动登录应用程序的Web浏览器并导航到正确查看活动的页面后,用户可以单击工具以保存其控制下的所有活动,也可以选择保存特定时段或所有时段。
问题是网站确实使用cookies,不允许打开另一个webbrowser;尽管根据我使用webbrowser
的观察结构构建了正确的网址,似乎拒绝了http请求尝试保存所有可用帐户的所有活动的非工作代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.IO;
using System.Text.RegularExpressions;
public partial class Form1 :Form
{
public Form1()
{
// ....... for simplicity and focus, I skip other code
and list only the relevant code that 'gets callled when use click the download all activity command tool
#region "prep dnlodActivity"
// get all available account number into sAccts
// and all period into activtyPeriod
// activtyPeriod[i,0] is used to set the url
string ActvtyPeriodID = "ActivityPeriodID", jscrpt = "OnAccountChangeLocalActivity()",
AcctDropdown;
string[,] sAccts, activtyPeriod;
HtmlElement heSelctdAcct = webBrowserDnLod.Document.GetElementById("hdnAccountsPage"),
heAcctDropdown = webBrowserDnLod.Document.GetElementById("AcctDropdown"),
heActivityPeriod = webBrowserDnLod.Document.GetElementById(ActvtyPeriodID),
heGo = webBrowserDnLod.Document.GetElementById("cellGoButton"),
heGoBtn = webBrowserDnLod.Document.GetElementById("AcctGoButton");
string acctInnerHtml = heAcctDropdown.InnerHtml,
goHtml = heGo.InnerHtml;
string sMsg, sActvtyRgx = @"<OPTION (selected ){0,1}value=(?<actvty>\w+)>(?<name>(\w| )+)<",
sJscrptRgx = @"onclick=""javascript:(?<jscrpt>(\w|[()])+);";
Match m = System.Text.RegularExpressions.Regex.Match(goHtml, sJscrptRgx, RegexParse4Lib.regexParse.roIcEc);
if (m.Success)
{
jscrpt = m.Groups[1].ToString().Replace("()", ""); //ChangeActivityPeriod
}
if (!RegexParse4Lib.regexParse.findAllExplicit(acctInnerHtml,
@"<OPTION (selected ){0,1}value=(?<acctID>\w+)>\w+ - (?<name>\w+( |\w|-)*)", RegexOptions.IgnoreCase,
false, false, out sAccts, out sMsg))
{
setStatus("failed to find account options- nothing saved for this session of Go autopilot");
addMsg(sMsg);
return;
}
if (!RegexParse4Lib.regexParse.findAllExplicit(heActivityPeriod.InnerHtml,//WebCtlDnLod.getAllText(),
sActvtyRgx, RegexOptions.IgnoreCase, false, false, out activtyPeriod, out sMsg))
{
setStatus("failed to find activity period options- nothing saved"); addMsg(sMsg);
return;
}
#endregion "prep dnlodActivity"
// that was easy and no problem
string sBaseUrl = webBrowserDnLod.Url.ToString();
const string selAcctParm = "&&SelectedAccount=",
AcctTypParm = "&SelectedAccountType";
int idxAcctTyp = sBaseUrl.IndexOf(AcctTypParm);
string sUrlTail = "&SelectedAccountType=RS-1&hdnAccountTypeStore=IN-1;RF-1;TF-1;RS-1;IN-2;IN-2;IN-2;TF-1;&hdnAccountsPage=&ActivityPeriod=";
if (idxAcctTyp > 0)
{
sUrlTail = sBaseUrl.Substring(idxAcctTyp);
sUrlTail = sUrlTail.Substring(0, sUrlTail.LastIndexOf("=") + 1);
sBaseUrl = sBaseUrl.Substring(0, sBaseUrl.IndexOf(selAcctParm));
}
string activityAsOfDt = "", curAcct;
string actvtyPeriodHtml = heActivityPeriod.InnerHtml;
int idxPeriod;
foreach (string sAcct in sAccts)
{
Util.Extract(actvtyPeriodHtml, @"value=(?<sel>\d{1,30})\sselected>", "${sel}", out activityAsOfDt);
for (idxPeriod = 0; idxPeriod < activtyPeriod.GetLength(0); idxPeriod++)
{
if (activtyPeriod[idxPeriod, 0].Length != 8) continue;
activityAsOfDt = activtyPeriod[idxPeriod, 0];
string sUrl = sBaseUrl + selAcctParm + sAcct + "&BackupAccount=" + sAcct
+ sUrlTail + activityAsOfDt +"&";
WebRequest wrGETURL;
wrGETURL = WebRequest.Create(sUrl);
wrGETURL.Proxy = WebProxy.GetDefaultProxy();
Util.tryAddCookie(wrGETURL, webBrowserDnLod.Document.Cookie, webBrowserDnLod.Document.Domain)
Stream objStream;
objStream = wrGETURL.GetResponse().GetResponseStream();
StreamReader objReader = new StreamReader(objStream);
string sHtml = objReader.ReadToEnd();
if (sLine.Contains("We cannot process your request"))
{ // always get executed:
MessageBox.Show(sUrl + Util.CsCrlf + Util.CsCrlf + sHtml, "failed to login");
return;
}
else // never gets here
{
MessageBox.Show(sHtml, "Great, got it");
// call the extract and save code
extractNSaveAllActivites(sHtml);
}
}
}
// I skip listing extractNSaveAllActivites as that is the the problem
}
public static Class Util
{
public static bool TryAddCookie(System.Net.WebRequest webRequest, string cookie, string domain)
{
System.Net.HttpWebRequest httpRequest = webRequest as System.Net.HttpWebRequest;
if (httpRequest == null)
{
return false;
}
if (httpRequest.CookieContainer == null)
{
httpRequest.CookieContainer = new System.Net.CookieContainer();
}
System.Net.Cookie cookie2 = new System.Net.Cookie("somename", cookie);
cookie2.Domain = domain;
cookie2.Secure = true; //cookie2.Expired = false;
cookie2.Expires = DateTime.Now.AddDays(75);
cookie2.Path = "Cookie:smith@www1.thebanksite.com/"
httpRequest.CookieContainer.Add(cookie2); // got flagged during runtime
/*
System.ArgumentException was unhandled
Message="The parameter '{0}' cannot be an empty string.\r\nParameter name: cookie.Domain"
Source="System"
ParamName="cookie.Domain"
StackTrace:
at System.Net.CookieContainer.Add(Cookie cookie)
...
*/
return true;
}
}
如何才能将HtmlDocumemt cookie从webbrowser正确转换为System.net.cookie?提前thx,非常感谢任何提示或参考。
我的主要工作是系统管理,一些数据库管理以及增加或添加小应用程序的小方面职责。所以请原谅我在httpsquest中的c#.net esp中的弱点 我已经做了很多谷歌搜索,但未能找到合适的关键词来获得结果。
我也在webbrowser中尝试过不同的方法,但是我无法使用webbrowser文档完成事件来处理有状态执行的复杂性。即使我在那里取得成功,维持也是一场噩梦。