根据评论中的建议,使用Web浏览器的方法似乎过于繁重,并且会受到其他环境限制。您最好的方法是创建一个单独的可测试的存储库来爬取数据 - 如果您确实需要(并且目标数据不会更改),则可以按需或提前使用蜘蛛方法。
是的,如果您尝试将其设置为ActiveX,则不同的浏览器将遇到问题。安全性可能不允许它。这里确实有很多因素;如果您的环境没有受到控制,那么这不是一个很好的选择。
假设您采用按需方法,我强烈建议创建一个可以引用的WebService或类。然后,您可以在服务器端使用开源解析器,例如:
- CsQuery(如果文档格式不正确),或者
- Fizzler(如果您可以信任文档完整性)。
基本上,您需要进行身份验证,存储您的身份验证cookie,最后通过第二个请求加载目标文档,并填充您的身份验证cookie。将该页面馈送到您的解析器(CsQuery或Fizzler)中。
执行登录的示例如下:
private HttpWebRequest PerformLoginRequest(CookieContainer container)
{
var request = (HttpWebRequest) WebRequest.Create(YOUR_POST_URL);
request.Method = "POST";
request.CookieContainer = container;
_logger.DebugFormat("Attempting login for '{0}'", _username);
var encoding = new ASCIIEncoding();
var credentials = string.Format("username={0}&password={1}", _username, _password);
byte[] data = encoding.GetBytes(credentials);
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = data.Length;
using (var requestStream = request.GetRequestStream())
{
try
{
requestStream.Write(data, 0, data.Length);
}
catch (Exception e)
{
_logger.Error("Error in login attempt.", e);
}
finally
{
requestStream.Close();
}
}
return request;
}
返回的 cookies 容器将有一个 set-cookie,您需要解析它,以便后续请求正确呈现身份验证位。我不得不这样做,并根据我在 SO 上找到的代码进行了工作,但现在找不到参考了。它可能看起来像这样(解释在 Set-Cookie 这里):
private static CookieContainer ProcessCookieContainer(HttpWebRequest request, CookieContainer container)
{
var response = (HttpWebResponse) request.GetResponse();
var cookierReader = new StreamReader(response.GetResponseStream());
string htmldoc = cookierReader.ReadToEnd();
var cookieHeader = response.GetResponseHeader("Set-Cookie");
response.Close();
container = new CookieContainer();
foreach (var cookie in cookieHeader.Split(','))
{
var split = cookie.Split(';');
string name = split[0].Split('=')[0];
string value = split[0].Split('=')[1];
var c = new Cookie(name, value) {Domain = "YourCookieDomain.com"};
container.Add(c);
}
return container;
}
而要加载一个文档进行解析,你可能会这样操作:
public string GetValueFromSomePage(int first, string second)
{
var container = new CookieContainer();
var request = PerformLoginRequest(container);
container = ProcessCookieContainer(request, container);
var result = string.Empty;
var requestUrl = string.Format("http://YourUrlWithParams.com/?first={0}&second={1}", 123, "abc");
var request = (HttpWebRequest)WebRequest.Create(requestUrl);
request.CookieContainer = container;
using (var serverResponse = (HttpWebResponse)request.GetResponse())
{
try
{
var reader = new StreamReader(serverResponse.GetResponseStream());
var responseDoc = new CQ(reader);
result = responseDoc["input[name=name]"].FirstElement().Value;
}
catch (Exception e)
{
_logger.Error("Error fetching data.", e);
}
finally
{
serverResponse.Close();
}
}
return result;
}
希望这能有所帮助。这里有一些需要注意的地方,但考虑到你的任务性质,你可能已经预料到了。
祝好。
System.Net.Http.HttpClient
或System.Net.WebRequest
来获取所需的内容? - Daniel Schilling