【问题标题】:HtmlAgilityPack.HtmlDocument CookiesHtmlAgilityPack.HtmlDocument Cookie
【发布时间】:2011-04-06 07:40:17
【问题描述】:

这与在脚本内设置的 cookie(可能在脚本标签内)有关。

System.Windows.Forms.HtmlDocument 执行这些脚本,并且可以通过其 Cookies 属性检索 cookie 集(如 document.cookie=etc...)。

我假设HtmlAgilityPack.HtmlDocument 不会这样做(执行)。我想知道是否有一种简单的方法可以模拟System.Windows.Forms.HtmlDocument 功能(cookie 部分)。

有人吗?

【问题讨论】:

  • 使用 HtmlAgilityPack.HtmlDocument

标签: javascript cookies html-agility-pack dom


【解决方案1】:

当我需要同时使用 CookiesHtmlAgilityPack 时,或者只是创建自定义请求(例如,设置 User-Agent 属性等),这就是我做:

  • 创建一个封装请求/响应的类。让我们称这个类为WebQuery
  • 在该类中有一个私有 CookieCollection(在您的情况下为 public)属性
  • 在类中创建一个手动执行请求的方法。签名可以是:

...

public HtmlAgilityPack.HtmlDocument GetSource(string url);

我们需要在这个方法中做什么?

好吧,使用HttpWebRequestHttpWebResponse,手动生成http请求(网上有几个例子说明如何做到这一点),创建一个@987654324的实例@class 使用接收流的构造函数。

我们必须使用什么流?嗯,返回的流:

httpResponse.GetResponseStream();

如果您使用HttpWebRequest 进行查询,您可以轻松地将其CookieContainer 属性设置为您在每次访问新页面之前声明的变量,这样all您访问的网站设置的 cookie 将正确存储在您在 WebQuery 类中声明的 CookieContainer 变量中,考虑到您只使用了 WebQuery 类的一个实例。

希望这个解释对你有用。考虑到使用它,你可以做任何你想做的事,不管 HtmlAgilityPack 是否支持它。

【讨论】:

    【解决方案2】:

    我还与 Rohit Agarwal 的 BrowserSession 类和 HtmlAgilityPack 一起工作。 但对我来说,“Get-function”的后续调用不起作用,因为每次都设置了新的 cookie。 这就是为什么我自己添加了一些功能。 (我的解决方案远非完美 - 它只是一个快速而肮脏的解决方案)但对我来说它有效,如果你不想花很多时间调查BrowserSession类,这就是我所做的:

    新增/修改功能如下:

    class BrowserSession{
       private bool _isPost;
       private HtmlDocument _htmlDoc;
       public CookieContainer cookiePot;   //<- This is the new CookieContainer
    
     ...
    
        public string Get2(string url)
        {
            HtmlWeb web = new HtmlWeb();
            web.UseCookies = true;
            web.PreRequest = new HtmlWeb.PreRequestHandler(OnPreRequest2);
            web.PostResponse = new HtmlWeb.PostResponseHandler(OnAfterResponse2);
            HtmlDocument doc = web.Load(url);
            return doc.DocumentNode.InnerHtml;
        }
        public bool OnPreRequest2(HttpWebRequest request)
        {
            request.CookieContainer = cookiePot;
            return true;
        }
        protected void OnAfterResponse2(HttpWebRequest request, HttpWebResponse response)
        {
            //do nothing
        }
        private void SaveCookiesFrom(HttpWebResponse response)
        {
            if ((response.Cookies.Count > 0))
            {
                if (Cookies == null)
                {
                    Cookies = new CookieCollection();
                }    
                Cookies.Add(response.Cookies);
                cookiePot.Add(Cookies);     //-> add the Cookies to the cookiePot
            }
        }
    

    它的作用:它基本上保存了初始“后响应”中的 cookie,并将相同的 CookieContainer 添加到稍后调用的请求中。我不完全理解为什么它在初始版本中不起作用,因为它在 AddCookiesTo 函数中以某种方式执行相同的操作。 (如果 (Cookies != null && Cookies.Count > 0) request.CookieContainer.Add(Cookies);) 无论如何,有了这些添加的功能,它现在应该可以正常工作了。

    可以这样使用:

    //initial "Login-procedure"
    BrowserSession b = new BrowserSession();
    b.Get("http://www.blablubb/login.php");
    b.FormElements["username"] = "yourusername";
    b.FormElements["password"] = "yourpass";
    string response = b.Post("http://www.blablubb/login.php");
    

    所有后续调用都应使用:

    response = b.Get2("http://www.blablubb/secondpageyouwannabrowseto");
    response = b.Get2("http://www.blablubb/thirdpageyouwannabrowseto");
    ...
    

    希望在您遇到同样问题时对您有所帮助。

    【讨论】:

    • PS public CookieContainer cookiePot; 必须是 public CookieContainer cookiePot = new CookieContainer;
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-14
    • 2010-12-29
    相关资源
    最近更新 更多