65.9K
CodeProject 正在变化。 阅读更多。
Home

m.Facebook 配合 C#

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.60/5 (40投票s)

2014年12月12日

CPOL

6分钟阅读

viewsIcon

183399

downloadIcon

2721

在不使用 Facebook API 的情况下,从 C# 代码执行您 Facebook 个人资料上的基本功能

已采纳建议。请继续提出您的建议、投票和评论,以改进此内容。

有关抓取步骤的指南,请参阅 此处

引言

Facebook Graph API 和许多其他 Facebook C# SDK 允许用户通过代码执行 Facebook 操作。但所有这些都需要 Facebook 应用的应用程序密钥、OATH 权限以及维护会话令牌的记录。我曾想过借助 HTTP GET 和 POST 来实现一些基本任务,例如登录、搜索、更新状态。为此,我使用了 Facebook 网站的移动版本。通过 `HTTPWebRequest`/`Response` 获取 `Response`,然后使用 Regex 解析 HTML 以获取所需数据。在需要时,`Response` 将通过 HTTP `Post` 方法发送。

背景

在我上一篇文章 《C# 中的多线程网页抓取》 中,我解释了使用 Regex、`WebClient` 以及 `HTTPWebRequest` 和 `Response` 进行网页抓取的技术。基于该文章中解释的技术,我编写了附带的代码。本文旨在解释:

  • 如何使用 HTTPWebRequest 和 HTTPWebResponse
  • 如何向 Web 服务器 GET 和 POST 数据
  • 如何收集 Cookie
  • 如何维护会话

类方法

名称

描述

public static Facebook Login(string username, string password)

获取 WebBrowser 控件的 Cookie 并将其存储在 Cookie Collection 中以维护会话

成功时返回 Facebook 对象,可以通过该对象调用其他公共方法

失败时,在默认浏览器中显示响应 HTML

public bool StatusUpdate(string txt)

更新用户时间线上的文本状态

public void UploadPhoto(string filepath, string caption)

将指定路径的图片上传到当前用户配置文件的移动上传文件夹,并附带指定说明

public Dictionary<string, string> SearchGroups(string keyword, int scount)

根据给定的关键字搜索群组,并从指定搜索结果计数开始返回群组 ID 和名称的字典

public Dictionary<string, string> SearchPages(string keyword, int scount)

根据给定的关键字搜索页面,并从指定搜索结果计数开始返回页面 URL 和名称的字典

Using the Code

执行登录

Facebook fb = Facebook.Login("USERNAME", "PASSWORD"); 

状态

fb.StatusUpdate("Text Status");

上传照片

fb.UploadPhoto(@"C:\Users\..\...\...\IMAGE.jpg", "Its the Caption");

搜索群组

            Dictionary<string, string> groups;
                    int startCount = 1;     //First Search Result Starts From 1
                    do
                    {
                        groups = fb.SearchGroups("diet coke", startCount);
        
                        //Next Page Results will Start From this Count
                        startCount += groups.Count;
                        //Traversing Through the Results
                        string txt = "";
                        foreach (string k in groups.Keys)
                            txt += k + "\t\t" + groups[k] + Environment.NewLine;
                        MessageBox.Show(txt);
                    } while (groups.Count > 0);

同样的方式,您也可以搜索页面。

代码如何工作?

  1. 在 C# 执行登录之前,让我们先在 Mozilla 中执行登录,并使用 LiveHTTPHeaders 分析 HTTP 标头。您可以从 Firefox 网站安装 LiveHTTPHeader 插件。启动 LiveHTTPHeader,浏览到 https://#,输入用户名和密码,然后点击登录按钮。浏览器发送的 HTTP Web 请求将如下所示:

  1. 第一行是发送用户名和密码的 URL(稍后在示例 3 中,我们将看到如何找到此 URL)。第二行指示使用的 HTTP 方法和版本,分别为 POST 和 1.1。

  2. 然后,所有字段都与我们之前在示例 1 中看到的普通 HTTP 标头一样。重要内容从 Cookie 标头开始。在示例 1 中,当我们浏览到 https://# 时,没有 Cookie 标头,但我们在响应标头中收到了一些 Cookie。现在,当我们点击登录按钮时,之前收到的 Cookie 集将在此 Cookie 标头中发送。

  3. 下一个标头显示内容类型。POST 数据主要使用两种内容类型:`application/x-www-form-urlencoded` 和 `multipart/form-data`。您可以在 此处 找到有关这些内容的更多信息。

  4. 下一个标头显示内容长度,最后一行显示内容。您将在该行中看到您的电子邮件地址和密码。实际上,最后一行显示的是通过 HTTP `Post` 方法发送到服务器的数据。

  5. 还有几个其他值。稍后在示例中,我们将看到这些值是什么,以及从哪里获取这些值!!!

  6. 让我们检查上面请求的响应标头。

  7. 响应标头显示了大量 Cookie。这些是服务器在成功登录后颁发的 Cookie。现在,对于任何后续请求,浏览器将这些 Cookie 发送给服务器,这样就可以维护会话。

  8. 转到“工具”->“清除最近的历史记录”并删除 Cookie,然后尝试浏览到您的 Facebook 个人资料页面,您会发现您将被重定向到 Facebook 登录页面。

  9. 现在,让我们创建上面截图中的相同登录请求标头,并测试是否能够成功登录。
    string getUrl = "https://#/login.php?login_attempt=1"; 
    
    string postData = "lsd=AVo_jqIy&email=YourEmailAddress
    &pass=YourPassword&default_persistent=0& 
    charset_test=%E2%82%AC%2C%C2%B4%2C%E2%82%AC%2C%C2%B4%2C%E6%B0%B4%2C%D0%94%2C%D0%84&
    timezone=-300&lgnrnd=072342_0iYK&lgnjs=1348842228&locale=en_US";
    HttpWebRequest getRequest = (HttpWebRequest)WebRequest.Create(getUrl);  
    getRequest.UserAgent = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.2 (KHTML, like Gecko) Firefox 15.0.0.1";
    getRequest.CookieContainer = new CookieContainer(); 
    //Adding Previously Received Cookies 
    getRequest.CookieContainer.Add(cookies); 
    getRequest.Method = WebRequestMethods.Http.Post;
    getRequest.ProtocolVersion = HttpVersion.Version11;
    getRequest.AllowAutoRedirect = false;
    getRequest.ContentType = "application/x-www-form-urlencoded"; 
    getRequest.Referer = "https://#"; 
    getRequest.KeepAlive = true;  
  10. `getUrl` 被分配给数据将要发布的地址,`postData` 变量是上面 HTTP 请求包中内容的副本。然后,我们创建了一个 `HTTPWebRequest` 对象,并设置了它的 User-Agent 标头。

  11. 在对 https://# 的请求的响应中收到的 Cookie 被添加到 `HTTPWebRequest` 对象中。如果我们不添加这些 Cookie,那么服务器将不会处理我们的登录请求,而是将我们重定向到登录页面。接下来,我们将 HTTP 方法设置为 Post,版本设置为 1.1(用于 HTTPS)。

  12. 对于我们尝试登录的请求,将 `AllowAutoRedirect` 属性设置为 `false` 非常重要。如果此属性设置为 `true`,那么 `HTTPWebRequest` 对象将跟随重定向响应。在重定向过程中,您可能会丢失对服务器在登录请求响应中发送的 Cookie 的访问权限。

  13. 现在,让我们将登录信息发送到服务器。

    //Converting postData to Array of Bytes    
    byte[] byteArray = Encoding.ASCII.GetBytes(postData); 
    //Setting Content-Length Header of the Request
    getRequest.ContentLength = byteArray.Length;
    //Obtaining the Stream To Write Data
    Stream newStream = getRequest.GetRequestStream();  
    //Writing Data To Stream
    newStream.Write(byteArray, 0, byteArray.Length);
    newStream.Close(); 
  14. 数据已写入流,现在让我们获取响应,看看我们收到了哪些 Cookie。

  15. 我们成功登录了系统并收到了 9 个 Cookie。上面的截图显示了有关收到 Cookie 的少量信息。您可以通过访问 Cookie 的属性来获取更多信息。将收到的 Cookie 添加到全局定义的 CookieCollection 中,以便在后续请求中使用。**如何检查登录是否成功?**通常,Cookie 的数量是判断登录是否成功的一种简单方法。为了更确定,您可以尝试获取主页的 HTML。如果您没有被重定向到登录页面,则表示您已成功登录。

    通过这种方式,您可以检查每个任务的发布数据,并编写 Regex 来查找页面 HTML 中的数据,然后生成后续的发布数据请求。上面的大多数函数都使用了这种机制。

关注点

尽管这些只是非常基本的功能,但通过理解这些功能,您可以增强代码以执行更高级的功能,例如加入群组、点赞页面、从时间线获取动态、向群组和页面发布图片、评论帖子、发送好友请求等。

注意:Facebook 类使用 Mozilla Firefox 的用户代理,您应该将其替换为您用于浏览 Facebook 的浏览器的用户代理。

将代码用于任何垃圾邮件活动可能会导致您的帐户被封禁。

© . All rights reserved.