Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用BrowserSession和HtmlAgilityPack通过.NET登录Facebook_C#_.net_Cookies_Html Agility Pack - Fatal编程技术网

C# 使用BrowserSession和HtmlAgilityPack通过.NET登录Facebook

C# 使用BrowserSession和HtmlAgilityPack通过.NET登录Facebook,c#,.net,cookies,html-agility-pack,C#,.net,Cookies,Html Agility Pack,我正在尝试使用Rohit Agarwal的类和HtmlAgilityPack一起登录Facebook,然后在Facebook上导航 我以前也通过编写自己的HttpWebRequest来做到这一点。但是,只有当我从浏览器中手动获取cookie并在每次执行新“会话”时向请求插入新的cookie字符串时,它才起作用。现在我尝试使用BrowserSession来获得更智能的导航 以下是当前代码: BrowserSession b = new BrowserSession(); b.Get(@"http

我正在尝试使用Rohit Agarwal的类和HtmlAgilityPack一起登录Facebook,然后在Facebook上导航

我以前也通过编写自己的HttpWebRequest来做到这一点。但是,只有当我从浏览器中手动获取cookie并在每次执行新“会话”时向请求插入新的cookie字符串时,它才起作用。现在我尝试使用BrowserSession来获得更智能的导航

以下是当前代码:

BrowserSession b = new BrowserSession();

b.Get(@"http://www.facebook.com/login.php");
b.FormElements["email"] = "some@email.com";
b.FormElements["pass"] = "xxxxxxxx";
b.FormElements["lsd"] = "qDhIH";
b.FormElements["trynum"] = "1";
b.FormElements["persistent_inputcheckbox"] = "1";

var response = b.Post(@"https://login.facebook.com/login.php?login_attempt=1");
以上方法很好。当我再次尝试使用此BrowserSession获取另一个页面时,麻烦就来了。我这样做是因为BrowserSession会保存上一个响应中的cookie并将它们插入下一个请求,因此我不必再手动插入从浏览器中获取的cookiedata

但是,当我尝试这样做时:

var profilePage = b.Get(@"https://m.facebook.com/profile.php?id=1111111111");
//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");
    protected bool OnPreRequest(HttpWebRequest request)
    {
        request.AllowAutoRedirect = false; // Location header messing up cookie handling!

        AddCookiesTo(request);               // Add cookies that were saved from previous requests
        if (_isPost) AddPostDataTo(request); // We only need to add post data on a POST request
        return true;
    }

我拿回来的文件是空的。如果您能告诉我我做错了什么,我将不胜感激。

您检查过他们的新API了吗?

您可以调用一个简单的URL来获取oauth2.0访问令牌,并将其附加到其余的请求上

https://graph.facebook.com/oauth/authorize?
    client_id=...&
    redirect_uri=http://www.example.com/oauth_redirect

将redirect_uri更改为您想要的任何URL,它将被回调,并带有一个名为“access_token”的参数。获取它并进行任何您想要的自动化SDK调用。

对不起,我对您提到的HTML agility pack或BrowserSession类了解不多。但我也尝试过同样的场景,效果很好。我正在使用一个.NET包装器(可以找到它的源代码,并对其进行详细解释),下面是我使用的代码(删除一些细节以保护无辜者):


希望这有帮助。

您可能需要使用或驱动浏览器。这将有助于确保您不必摆弄cookies,也不必进行任何自定义工作,以使后续请求正常工作,因为您正在模拟实际用户。

今天,我也面临着同样的问题。我还与Rohit Agarwal的课程以及HtmlAgilityPack一起工作。 经过一整天的尝试和错误编程,我发现问题是由没有在后续请求中设置正确的cookie引起的。 我无法更改初始BrowserSession代码以使其正常工作,但我添加了以下函数,并稍微修改了SameCookieFrom函数。最后,它对我很有效

添加/修改的功能如下:

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
        }
    }
所有后续通话应使用:

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

我希望它能帮助许多面临同样问题的人

如果有人在乎的话,我已经解决了这个问题的根本原因。原来cookies保存在请求对象的CookieContainer中,而不是响应对象。我还添加了下载文件的功能(前提是该文件是基于字符串的)。代码肯定不是线程安全的,但对象一开始就不是线程安全的:

public class BrowserSession
{
    private bool _isPost;
    private bool _isDownload;
    private HtmlDocument _htmlDoc;
    private string _download;

    /// <summary>
    /// System.Net.CookieCollection. Provides a collection container for instances of Cookie class 
    /// </summary>
    public CookieCollection Cookies { get; set; }

    /// <summary>
    /// Provide a key-value-pair collection of form elements 
    /// </summary>
    public FormElementCollection FormElements { get; set; }

    /// <summary>
    /// Makes a HTTP GET request to the given URL
    /// </summary>
    public string Get(string url)
    {
        _isPost = false;
        CreateWebRequestObject().Load(url);
        return _htmlDoc.DocumentNode.InnerHtml;
    }

    /// <summary>
    /// Makes a HTTP POST request to the given URL
    /// </summary>
    public string Post(string url)
    {
        _isPost = true;
        CreateWebRequestObject().Load(url, "POST");
        return _htmlDoc.DocumentNode.InnerHtml;
    }

    public string GetDownload(string url)
    {
        _isPost = false;
        _isDownload = true;
        CreateWebRequestObject().Load(url);
        return _download;
    }

    /// <summary>
    /// Creates the HtmlWeb object and initializes all event handlers. 
    /// </summary>
    private HtmlWeb CreateWebRequestObject()
    {
        HtmlWeb web = new HtmlWeb();
        web.UseCookies = true;
        web.PreRequest = new HtmlWeb.PreRequestHandler(OnPreRequest);
        web.PostResponse = new HtmlWeb.PostResponseHandler(OnAfterResponse);
        web.PreHandleDocument = new HtmlWeb.PreHandleDocumentHandler(OnPreHandleDocument);
        return web;
    }

    /// <summary>
    /// Event handler for HtmlWeb.PreRequestHandler. Occurs before an HTTP request is executed.
    /// </summary>
    protected bool OnPreRequest(HttpWebRequest request)
    {
        AddCookiesTo(request);               // Add cookies that were saved from previous requests
        if (_isPost) AddPostDataTo(request); // We only need to add post data on a POST request
        return true;
    }

    /// <summary>
    /// Event handler for HtmlWeb.PostResponseHandler. Occurs after a HTTP response is received
    /// </summary>
    protected void OnAfterResponse(HttpWebRequest request, HttpWebResponse response)
    {
        SaveCookiesFrom(request, response); // Save cookies for subsequent requests

        if (response != null && _isDownload)
        {
            Stream remoteStream = response.GetResponseStream();
            var sr = new StreamReader(remoteStream);
            _download = sr.ReadToEnd();
        }
    }

    /// <summary>
    /// Event handler for HtmlWeb.PreHandleDocumentHandler. Occurs before a HTML document is handled
    /// </summary>
    protected void OnPreHandleDocument(HtmlDocument document)
    {
        SaveHtmlDocument(document);
    }

    /// <summary>
    /// Assembles the Post data and attaches to the request object
    /// </summary>
    private void AddPostDataTo(HttpWebRequest request)
    {
        string payload = FormElements.AssemblePostPayload();
        byte[] buff = Encoding.UTF8.GetBytes(payload.ToCharArray());
        request.ContentLength = buff.Length;
        request.ContentType = "application/x-www-form-urlencoded";
        System.IO.Stream reqStream = request.GetRequestStream();
        reqStream.Write(buff, 0, buff.Length);
    }

    /// <summary>
    /// Add cookies to the request object
    /// </summary>
    private void AddCookiesTo(HttpWebRequest request)
    {
        if (Cookies != null && Cookies.Count > 0)
        {
            request.CookieContainer.Add(Cookies);
        }
    }

    /// <summary>
    /// Saves cookies from the response object to the local CookieCollection object
    /// </summary>
    private void SaveCookiesFrom(HttpWebRequest request, HttpWebResponse response)
    {
        //save the cookies ;)
        if (request.CookieContainer.Count > 0 || response.Cookies.Count > 0)
        {
            if (Cookies == null)
            {
                Cookies = new CookieCollection();
            }

            Cookies.Add(request.CookieContainer.GetCookies(request.RequestUri));
            Cookies.Add(response.Cookies);
        }
    }

    /// <summary>
    /// Saves the form elements collection by parsing the HTML document
    /// </summary>
    private void SaveHtmlDocument(HtmlDocument document)
    {
        _htmlDoc = document;
        FormElements = new FormElementCollection(_htmlDoc);
    }
}

/// <summary>
/// Represents a combined list and collection of Form Elements.
/// </summary>
public class FormElementCollection : Dictionary<string, string>
{
    /// <summary>
    /// Constructor. Parses the HtmlDocument to get all form input elements. 
    /// </summary>
    public FormElementCollection(HtmlDocument htmlDoc)
    {
        var inputs = htmlDoc.DocumentNode.Descendants("input");
        foreach (var element in inputs)
        {
            string name = element.GetAttributeValue("name", "undefined");
            string value = element.GetAttributeValue("value", "");

            if (!this.ContainsKey(name))
            {
                if (!name.Equals("undefined"))
                {
                    Add(name, value);
                }
            }
        }
    }

    /// <summary>
    /// Assembles all form elements and values to POST. Also html encodes the values.  
    /// </summary>
    public string AssemblePostPayload()
    {
        StringBuilder sb = new StringBuilder();
        foreach (var element in this)
        {
            string value = System.Web.HttpUtility.UrlEncode(element.Value);
            sb.Append("&" + element.Key + "=" + value);
        }
        return sb.ToString().Substring(1);
    }
}
公共类浏览器会话
{
私人书店;
私人住宅是低负荷的;
私人HtmlDocument_htmlDoc;
私人字符串下载;
/// 
///System.Net.CookieCollection。为Cookie类的实例提供收集容器
/// 
公共CookieCollection Cookies{get;set;}
/// 
///提供表单元素的键值对集合
/// 
public formelement集合FormElements{get;set;}
/// 
///对给定URL发出HTTP GET请求
/// 
公共字符串获取(字符串url)
{
_isPost=false;
CreateWebRequestObject().Load(url);
返回_htmlDoc.DocumentNode.InnerHtml;
}
/// 
///向给定URL发出HTTP POST请求
/// 
公共字符串帖子(字符串url)
{
_isPost=true;
CreateWebRequestObject().Load(url,“POST”);
返回_htmlDoc.DocumentNode.InnerHtml;
}
公共字符串GetDownload(字符串url)
{
_isPost=false;
_isDownload=true;
CreateWebRequestObject().Load(url);
返回下载;
}
/// 
///创建HtmlWeb对象并初始化所有事件处理程序。
/// 
私有HtmlWeb CreateWebRequestObject()
{
HtmlWeb web=新的HtmlWeb();
web.UseCookies=true;
web.PreRequest=新的HtmlWeb.PreRequestHandler(OnPreRequest);
web.PostResponse=新的HtmlWeb.PostResponseHandler(OnAfterResponse);
web.PreHandleDocument=新的HtmlWeb.PreHandleDocumentHandler(OnPreHandleDocument);
返回网页;
}
/// 
///HtmlWeb.PreRequestHandler.的事件处理程序。在执行HTTP请求之前发生。
/// 
受保护的bool OnPreRequest(HttpWebRequest请求)
{
AddCookiesTo(请求);//添加以前请求中保存的cookie
if(_isPost)AddPostDataTo(request);//我们只需要在post请求中添加post数据
返回true;
}
/// 
///HtmlWeb.PostResponseHandler.的事件处理程序在收到HTTP响应后发生
/// 
受保护的无效OnAfterResponse(HttpWebRequest请求,HttpWebResponse响应)
{
SaveCookiesFrom(请求、响应);//为后续请求保存cookies
if(响应!=null&&u isDownload)
{
Stream remoteStream=response.GetResponseStream();
var sr=新的StreamReader(remoteStream);
_下载=sr.ReadToEnd();
}
}
/// 
///HtmlWeb.PreHandleDocumentHandler.的事件处理程序。在处理HTML文档之前发生
/// 
预处理文档上的受保护无效(HtmlDocument文档)
{
保存HTMLDocument(文档);
}
/// 
///组装Post数据并附加到请求对象
/// 
私有void AddPostDataTo(HttpWebRequest请求)
{
字符串负载=FormElements.AssemblePostPayload();
byte[]buff=Encoding.UTF8.GetBytes(payload.tocharray());
request.ContentLength=buff.Length;
request.ContentType=“应用程序/x-www-
    request.AllowAutoRedirect = false; // Location header messing up cookie handling!
    protected bool OnPreRequest(HttpWebRequest request)
    {
        request.AllowAutoRedirect = false; // Location header messing up cookie handling!

        AddCookiesTo(request);               // Add cookies that were saved from previous requests
        if (_isPost) AddPostDataTo(request); // We only need to add post data on a POST request
        return true;
    }