12

在下面的代码中,我可以使用 HTMLAgilitypack 设置用户名和密码的值,但我无法调用登录按钮的单击事件(按钮源代码中的 id 为“s1”)。

无论如何要这样做吗?我不使用的原因WebBrowser是因为我需要 HTMLAgilityPack 从源代码中没有 ID 的页面检索数据。

var doc = new HtmlWeb().Load("http://MYURL.com");
doc.DocumentNode.SelectSingleNode("name").SetAttributeValue("value", "MyUsername");
doc.DocumentNode.SelectSingleNode("password").SetAttributeValue("value", "MyPassword");
4

3 回答 3

7

无论如何要这样做吗?

不是 HTML Agility Pack (HAP) 库提供的——不是直接的。

HAP 非常适合获取单个页面并对其进行解析,但它不是为持续交互而设计的。缺少的东西是 cookie 管理、JavaScript 交互等等。

为了登录,您可能需要向服务器发送一个 HTTP POST,包括您想要的数据——HAP 对此无能为力。

您将需要使用类似的类WebRequest来发布帖子 - 我建议查看fiddler并使用它来查看请求的外观并相应地构建它,尽管这可能只是第一步。

您可能想要研究使用 web 自动化工具,例如seleniumWatiN

于 2012-11-26T16:31:28.097 回答
4

您需要通过 fiddler 观察 POST 请求并查看其结构。例如 :

    {"userName":"you","password":"pwd"}

通常,网站会通过在您的请求中接收他们的 cookie 来识别您已登录。

默认情况下, HttpClient将从特定域接收到的 cookie 与每个顺序请求一起发送到该域(直到您处置该 HttpClient 实例)

1) 创建一个 cookie 容器并将其分配给您的 HttpClient 实例。

2) 使用 HttpClient 发出登录 POST 请求。

3) 使用 HttpClient 进行数据 GET 请求。

4) 从响应中读取 html 字符串。

5) 使用 HtmlAgilityPack HtmlDocument 从 html 字符串加载文档,而不是从网络加载文档(如大多数示例所示)。

 string baseUrl = "https://www.yourwebsite.com";
 string loginUrl = "/Account/LogOn"; 
 string sessionUrl = "/Data";

 var uri = new Uri(baseUrl);

 CookieContainer cookies = new CookieContainer();
 HttpClientHandler handler = new HttpClientHandler();
 handler.CookieContainer = cookies;

 using (var client = new HttpClient(handler))
 {
       client.BaseAddress = uri;

       var request = new { userName = "you", password = "pwd" };
       var resLogin = client.PostAsJsonAsync(loginUrl,request).Result;
       if (resLogin.StatusCode != HttpStatusCode.OK)
            Console.WriteLine("Could not login -> StatusCode = " + resLogin.StatusCode);

       // see what cookies are returned   
      IEnumerable<Cookie> responseCookies = cookies.GetCookies(uri).Cast<Cookie>();
      foreach (Cookie cookie in responseCookies)
            Console.WriteLine(cookie.Name + ": " + cookie.Value);

      var resData = client.GetAsync(dataUrl).Result;
      if(resSession.StatusCode != HttpStatusCode.OK)
            Console.WriteLine("Could not get data html -> StatusCode = " + resSession.StatusCode);

       var html = resSession.Content.ReadAsStringAsync().Result;

       var doc = new HtmlDocument();
       doc.LoadHtml(html);
 }
于 2017-08-24T18:19:17.200 回答
0

我不知道你是否使用 WPF WebBrowser 控件,但如果你是,你可以使用类似的东西

doc.GetElementById("submit_signin").Click();

这对我有用。

于 2012-11-27T18:41:12.730 回答