使用HTMLAgilityPack登录网站

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");
3个回答

8

有没有办法可以做到这一点?

使用HTML Agility Pack(HAP)库提供的功能是不行的 - 直接无法实现。

HAP非常适合获取单个页面并解析它,但它不适用于持续交互。缺少的功能包括cookie管理、JavaScript交互等。

为了登录,您可能需要向服务器发送HTTP POST请求,包括您想要的数据 - HAP无法帮助您完成此操作。

您需要使用类似于WebRequest的类来进行POST - 建议查看fiddler并使用它来查看请求应该是什么样子的,并相应地构建它,尽管这可能只是第一步。

您可能需要调查使用Web自动化工具,如seleniumWatiN


谢谢你的帮助。我已经看了一下,但由于我登录的网站源代码很奇怪,所以我肯定需要使用HTMLAgilityPack。我已经做了一些事情,但之后有点卡住了:我通过webbrowser1控件登录,然后检索该会话的cookie。我能否应用该cookie并使用HTMLAgilityPack打开一个页面? - touyets
1
@user1842134 - 不,HAP 不能处理 cookies。 - Oded

5

您需要通过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字符串加载文档,而不是像大多数示例所示的从Web加载。
 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);
 }

0
我不知道你是否在使用WPF WebBrowser控件,但如果是的话,你可以使用类似以下的内容。
doc.GetElementById("submit_signin").Click();

这对我来说是有效的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接