facebook_facebook 职级 - CSDN
精华内容
参与话题
  • facebook登录和分享

    千次阅读 2019-08-20 15:46:54
    整体来说,Facebook在国际化中做的是非常好的。也是,Twitter和YouTube都是Google自己家的,在中国政府受挫之后,就不方便投入太多,怎么做都好像一个血脉,一个味道。 然后Facebook就不一样,小札的丈母娘祖上...

              整体来说,Facebook在国际化中做的是非常好的。也是,Twitter和YouTube都是Google自己家的,在中国政府受挫之后,就不方便投入太多,怎么做都好像一个血脉,一个味道。

              然后Facebook就不一样,小札的丈母娘祖上就是中国的,而且小札年轻,特别喜欢和挑战新的事务。。据说,Facebook为了在非洲的使用体验,专门派工程师到非常调研,非常到位的。

     

    Facebook 的开发者支持分成两块:

            账户登录 Account login,和 Account Kit 。

    提供的这两个服务,都提供了各种平台的支持,ios,andorid,web,mobilePhone等等。

     

    Account Kit 提供电话号码和邮箱登录功能,无需玩家记忆任何其他密码。

    “Facebook 登录”让玩家能够使用他们现有的 Facebook 帐户两步轻松完成帐户注册。

    两者结合使用,效果更好 — 可用于壮大您的客户群。

    2018 年 8 月之前,Account Kit 不会收取任何短信费用,之后会按照标准的短信费率,对每月确认短信数量超出 10 万的应用收费。

     

    应该说,这两个功能属于异曲同工的作用,具体的使用可以参考产品和业务的需要进行选型,。。在开发的时候,可以同时继承和包装,需要的时候,直接使用。

     

    AndroidSDK文档:https://developers.facebook.com/docs/accountkit/android

    客户端SDK_android下载:https://developers.facebook.com/docs/android

    一,用户登录

    好了,下面开始进行具体的步骤了::

        1,跟所有的三方账户一样,注册开发者账户,创建应用,获得应用编号口令什么的。

        2,gradle配置

    repositories {
      jcenter()
    }
    
    dependencies {
      compile 'com.facebook.android:account-kit-sdk:4.+'
    }
    {
      jcenter()
    }
    
    dependencies {
      compile 'com.facebook.android:account-kit-sdk:4.+'
    }

        3,配置manifest

    <meta-data android:name="com.facebook.accountkit.ApplicationName"
               android:value="@string/app_name" />
    <meta-data android:name="com.facebook.sdk.ApplicationId"
               android:value="@string/FACEBOOK_APP_ID" />
    <meta-data android:name="com.facebook.accountkit.ClientToken"
               android:value="@string/ACCOUNT_KIT_CLIENT_TOKEN" />
    
    <activity
      android:name="com.facebook.accountkit.ui.AccountKitActivity" />
     android:name="com.facebook.accountkit.ApplicationName"
               android:value="@string/app_name" />
    <meta-data android:name="com.facebook.sdk.ApplicationId"
               android:value="@string/FACEBOOK_APP_ID" />
    <meta-data android:name="com.facebook.accountkit.ClientToken"
               android:value="@string/ACCOUNT_KIT_CLIENT_TOKEN" />
    
    <activity
      android:name="com.facebook.accountkit.ui.AccountKitActivity" />

        根据应用的情况,可能需要更多的配置,允许AccountKitActivity的启动,

    <activity
      android:name="com.facebook.accountkit.ui.AccountKitActivity"
      android:theme="@style/AppLoginTheme"
      tools:replace="android:theme" />
    
      android:name="com.facebook.accountkit.ui.AccountKitActivity"
      android:theme="@style/AppLoginTheme"
      tools:replace="android:theme" />

        4*,如果想禁用应用内事件,可以加入。。这里默认的value是true。。这里的应用内事件表示 AccountKit 登录展示 ,AccountKit登录开始,AccountKit登录尝试,AccountKit的登录。这里的统计可以在控制面板的漏斗里面看到。

    <meta-data android:name="com.facebook.accountkit.FacebookAppEventsEnabled"
               android:value="false"/>
     android:name="com.facebook.accountkit.FacebookAppEventsEnabled"
               android:value="false"/>

        5,检查当前会话,意思就是登录之后的回调类似于。当在开发者的控制面板里启用客户端的访问口令流程,登录状态就会传给客户端程序。
     

    import com.facebook.accountkit.AccountKit;
    import com.facebook.accountkit.AccessToken;
    
    AccessToken accessToken = AccountKit.getCurrentAccessToken();
    
    if (accessToken != null) {
      //Handle Returning User
    } else {
      //Handle new or logged out user
    }
     com.facebook.accountkit.AccountKit;
    import com.facebook.accountkit.AccessToken;
    
    AccessToken accessToken = AccountKit.getCurrentAccessToken();
    
    if (accessToken != null) {
      //Handle Returning User
    } else {
      //Handle new or logged out user
    }

        6,短信登录流程。
     

    import com.facebook.accountkit.AccountKit;
    
    public static int APP_REQUEST_CODE = 99;
    
    public void phoneLogin(final View view) {
      final Intent intent = new Intent(getActivity(), AccountKitActivity.class);
      AccountKitConfiguration.AccountKitConfigurationBuilder configurationBuilder =
        new AccountKitConfiguration.AccountKitConfigurationBuilder(
          LoginType.PHONE,
          AccountKitActivity.ResponseType.CODE); // or .ResponseType.TOKEN
      // ... perform additional configuration ...
      intent.putExtra(
        AccountKitActivity.ACCOUNT_KIT_ACTIVITY_CONFIGURATION,
        configurationBuilder.build());
      startActivityForResult(intent, APP_REQUEST_CODE);
    }
     com.facebook.accountkit.AccountKit;
    
    public static int APP_REQUEST_CODE = 99;
    
    public void phoneLogin(final View view) {
      final Intent intent = new Intent(getActivity(), AccountKitActivity.class);
      AccountKitConfiguration.AccountKitConfigurationBuilder configurationBuilder =
        new AccountKitConfiguration.AccountKitConfigurationBuilder(
          LoginType.PHONE,
          AccountKitActivity.ResponseType.CODE); // or .ResponseType.TOKEN
      // ... perform additional configuration ...
      intent.putExtra(
        AccountKitActivity.ACCOUNT_KIT_ACTIVITY_CONFIGURATION,
        configurationBuilder.build());
      startActivityForResult(intent, APP_REQUEST_CODE);
    }

            APP_REQUEST_CODE 是您用于追踪登录流程的自定义代码。它可以是任何整数,但需要由您的应用程序设置。
            初始化 intent(意图)附加程序时,请务必指定与 Facebook 开发者门户网站面板中的应用授权设置相匹配的 AccountKitActivity.ResponseType:如果您的应用面板的启用客户端访问口令流程开关设置为“开”,则指定为TOKEN,如果设置为“关”,则指定为 CODE。

         7,邮箱登录流程

    import com.facebook.accountkit.AccountKit;
    
    public static int APP_REQUEST_CODE = 99;
    
    public void emailLogin(final View view) {
      final Intent intent = new Intent(getActivity(), AccountKitActivity.class);
      AccountKitConfiguration.AccountKitConfigurationBuilder configurationBuilder =
        new AccountKitConfiguration.AccountKitConfigurationBuilder(
          LoginType.EMAIL,
          AccountKitActivity.ResponseType.CODE); // or .ResponseType.TOKEN
      // ... perform additional configuration ...
      intent.putExtra(
        AccountKitActivity.ACCOUNT_KIT_ACTIVITY_CONFIGURATION,
        configurationBuilder.build());
      startActivityForResult(intent, APP_REQUEST_CODE);
    }
     com.facebook.accountkit.AccountKit;
    
    public static int APP_REQUEST_CODE = 99;
    
    public void emailLogin(final View view) {
      final Intent intent = new Intent(getActivity(), AccountKitActivity.class);
      AccountKitConfiguration.AccountKitConfigurationBuilder configurationBuilder =
        new AccountKitConfiguration.AccountKitConfigurationBuilder(
          LoginType.EMAIL,
          AccountKitActivity.ResponseType.CODE); // or .ResponseType.TOKEN
      // ... perform additional configuration ...
      intent.putExtra(
        AccountKitActivity.ACCOUNT_KIT_ACTIVITY_CONFIGURATION,
        configurationBuilder.build());
      startActivityForResult(intent, APP_REQUEST_CODE);
    }

    点击邮件的地址回到应用,需要一个中间者进行重定向。

    <activity android:name="com.facebook.accountkit.ui.AccountKitEmailRedirectActivity">
       <intent-filter>
         <action android:name="android.intent.action.VIEW" />
         <category android:name="android.intent.category.DEFAULT" />
         <category android:name="android.intent.category.BROWSABLE" />
         <data android:scheme="@string/ak_login_protocol_scheme" />
      </intent-filter>
    </activity>
     android:name="com.facebook.accountkit.ui.AccountKitEmailRedirectActivity">
       <intent-filter>
         <action android:name="android.intent.action.VIEW" />
         <category android:name="android.intent.category.DEFAULT" />
         <category android:name="android.intent.category.BROWSABLE" />
         <data android:scheme="@string/ak_login_protocol_scheme" />
      </intent-filter>
    </activity>
    
    
    // if your Facebook App ID is 1234567, you should use ak1234567
    <string name="ak_login_protocol_scheme">akFACEBOOK_APP_ID</string>
    
    <string name="ak_login_protocol_scheme">akFACEBOOK_APP_ID</string>


    API的其他功能:
           AccountKitConfigurationBuilder 对象通过提供允许您在运行时改写默认属性的方法。
           setInitialAuthState(String initialAuthState)           (可选)由开发者生成的一个随机数,用于确认收到的响应与请求匹配。
            setInitialEmail(String initialEmail)        (可选)在邮箱登录流程中预填充用户的电子邮箱。
            setDefaultCountryCode(String defaultCountryCode)          (可选)设置短信登录流程中默认显示的国家/地区代码。
            setInitialPhoneNumber(PhoneNumber initialPhoneNumber)             (可选)在短信登录流程中预填充用户的手机号码。
            setFacebookNotificationsEnabled(boolean facebookNotificationsEnabled)       (可选)如果设置此标记,Account Kit 就会向用户提供在短信发送失败后,通过 Facebook 通知接收验证消息的选项,前提是他们的手机号码与 Facebook 帐户关联。关联的手机号码必须是 Facebook 帐户的主要手机号码。
    默认:true
             setReadPhoneStateEnabled(boolean readPhoneStateEnabled);
             setReceiveSMS(boolean receiveSMSEnabled);
             setSMSWhitelist(String[] smsWhitelist);
             setSMSBlacklist(String[] smsBlacklist);

     

     

    下面一大块,是自定制Android UI部分的:

    开发者SDK:https://developers.facebook.com/docs/accountkit/android/customizing

        基本UI:

               经典:

              半透明:

              现代:

        高级UI:

    为应用添加皮肤:

    // constructor without a background image
    AccountKitConfiguration.AccountKitConfigurationBuilder configurationBuilder;
    UIManager uiManager;
    
    // Skin is CLASSIC, CONTEMPORARY, or TRANSLUCENT
    uiManager = new SkinManager(
                Skin <skin>,
                @ColorInt int <primaryColor>);
    configurationBuilder.setUIManager(uiManager);
    AccountKitConfiguration.AccountKitConfigurationBuilder configurationBuilder;
    UIManager uiManager;
    
    // Skin is CLASSIC, CONTEMPORARY, or TRANSLUCENT
    uiManager = new SkinManager(
                Skin <skin>,
                @ColorInt int <primaryColor>);
    configurationBuilder.setUIManager(uiManager);
    // constructor with a background image imageAccountKitConfiguration.AccountKitConfigurationBuilder configurationBuilder;
    UIManager uiManager;
    // Skin is CLASSIC, CONTEMPORARY, or TRANSLUCENT
    // Tint is WHITE or BLACK
    // TintIntensity is a value between 55-85%
    uiManager = new SkinManager(
                Skin <skin>,
                @ColorInt int <primaryColor>,
                @DrawableRes int <backgroundImage>,
                Tint <tint>,
                double <tintIntensity>);
    configurationBuilder.setUIManager(uiManager);
    UIManager uiManager;
    // Skin is CLASSIC, CONTEMPORARY, or TRANSLUCENT
    // Tint is WHITE or BLACK
    // TintIntensity is a value between 55-85%
    uiManager = new SkinManager(
                Skin <skin>,
                @ColorInt int <primaryColor>,
                @DrawableRes int <backgroundImage>,
                Tint <tint>,
                double <tintIntensity>);
    configurationBuilder.setUIManager(uiManager);

    高级UI部分:

    public class MyAdvancedUIManager extends BaseUIManager {
    
        private final ButtonType confirmButton;
        private final ButtonType entryButton;
        private final TextPosition textPosition;
    
        public MyAdvancedUIManager(
                final ButtonType confirmButton,
                final ButtonType entryButton,
                final LoginType loginType,
                final TextPosition textPosition,
                final int themeResourceId) {
            super(loginType, themeResourceId);
            this.confirmButton = confirmButton;
            this.entryButton = entryButton;
            this.textPosition = textPosition;
        }
    
        private MyAdvancedUIManager(final Parcel source) {
            super(source);
            String s = source.readString();
            final ButtonType confirmButton = s == null ? null : ButtonType.valueOf(s);
            s = source.readString();
            final ButtonType entryButton = s == null ? null : ButtonType.valueOf(s);
            s = source.readString();
            final TextPosition textPosition = s == null ? null : TextPosition.valueOf(s);
            this.confirmButton = confirmButton;
            this.entryButton = entryButton;
            this.textPosition = textPosition;
        }
    
        @Override
        @Nullable
        public Fragment getHeaderFragment(final LoginFlowState state) {
            Fragment headerFragment;
            switch (state) {
                case PHONE_NUMBER_INPUT:
                case EMAIL_INPUT:
                case EMAIL_VERIFY:
                case SENDING_CODE:
                case SENT_CODE:
                case CODE_INPUT:
                case VERIFYING_CODE:
                case VERIFIED:
                case ACCOUNT_VERIFIED:
                case CONFIRM_ACCOUNT_VERIFIED:
                case CONFIRM_INSTANT_VERIFICATION_LOGIN:
                    // insert appropriate customizations for headerFragment
                case ERROR:
                    // handle appropriate error for headerFragment
                default:
                    headerFragment = new Fragment();
            }
    
            return headerFragment;
        }
    
        public @Nullable ButtonType getButtonType(final LoginFlowState state) {
            switch (state) {
                case PHONE_NUMBER_INPUT:
                    return entryButton;
                case EMAIL_INPUT:
                    return entryButton;
                case CODE_INPUT:
                    return confirmButton;
                default:
                    return null;
            }
        }
    
        @Override
        public void onError(final AccountKitError error) {
            // handle error
        }
    
        @Override
        public void writeToParcel(final Parcel dest, final int flags) {
            super.writeToParcel(dest, flags);
            dest.writeString(confirmButton != null ? confirmButton.name() : null);
            dest.writeString(entryButton != null ? entryButton.name() : null);
            dest.writeString(textPosition != null ? textPosition.name() : null);
        }
    
        public static final Creator<MyAdvancedUIManager> CREATOR
                = new Creator<MyAdvancedUIManager>() {
            @Override
            public MyAdvancedUIManager createFromParcel(final Parcel source) {
                return new MyAdvancedUIManager(source);
            }
    
            @Override
            public MyAdvancedUIManager[] newArray(final int size) {
                return new MyAdvancedUIManager[size];
            }
        };
    } class MyAdvancedUIManager extends BaseUIManager {
    
        private final ButtonType confirmButton;
        private final ButtonType entryButton;
        private final TextPosition textPosition;
    
        public MyAdvancedUIManager(
                final ButtonType confirmButton,
                final ButtonType entryButton,
                final LoginType loginType,
                final TextPosition textPosition,
                final int themeResourceId) {
            super(loginType, themeResourceId);
            this.confirmButton = confirmButton;
            this.entryButton = entryButton;
            this.textPosition = textPosition;
        }
    
        private MyAdvancedUIManager(final Parcel source) {
            super(source);
            String s = source.readString();
            final ButtonType confirmButton = s == null ? null : ButtonType.valueOf(s);
            s = source.readString();
            final ButtonType entryButton = s == null ? null : ButtonType.valueOf(s);
            s = source.readString();
            final TextPosition textPosition = s == null ? null : TextPosition.valueOf(s);
            this.confirmButton = confirmButton;
            this.entryButton = entryButton;
            this.textPosition = textPosition;
        }
    
        @Override
        @Nullable
        public Fragment getHeaderFragment(final LoginFlowState state) {
            Fragment headerFragment;
            switch (state) {
                case PHONE_NUMBER_INPUT:
                case EMAIL_INPUT:
                case EMAIL_VERIFY:
                case SENDING_CODE:
                case SENT_CODE:
                case CODE_INPUT:
                case VERIFYING_CODE:
                case VERIFIED:
                case ACCOUNT_VERIFIED:
                case CONFIRM_ACCOUNT_VERIFIED:
                case CONFIRM_INSTANT_VERIFICATION_LOGIN:
                    // insert appropriate customizations for headerFragment
                case ERROR:
                    // handle appropriate error for headerFragment
                default:
                    headerFragment = new Fragment();
            }
    
            return headerFragment;
        }
    
        public @Nullable ButtonType getButtonType(final LoginFlowState state) {
            switch (state) {
                case PHONE_NUMBER_INPUT:
                    return entryButton;
                case EMAIL_INPUT:
                    return entryButton;
                case CODE_INPUT:
                    return confirmButton;
                default:
                    return null;
            }
        }
    
        @Override
        public void onError(final AccountKitError error) {
            // handle error
        }
    
        @Override
        public void writeToParcel(final Parcel dest, final int flags) {
            super.writeToParcel(dest, flags);
            dest.writeString(confirmButton != null ? confirmButton.name() : null);
            dest.writeString(entryButton != null ? entryButton.name() : null);
            dest.writeString(textPosition != null ? textPosition.name() : null);
        }
    
        public static final Creator<MyAdvancedUIManager> CREATOR
                = new Creator<MyAdvancedUIManager>() {
            @Override
            public MyAdvancedUIManager createFromParcel(final Parcel source) {
                return new MyAdvancedUIManager(source);
            }
    
            @Override
            public MyAdvancedUIManager[] newArray(final int size) {
                return new MyAdvancedUIManager[size];
            }
        };
    }
    public class CustomAdvancedUIManager extends BaseUIManager {
        /*implementation here */
    }
    UIManager advancedUIManager = new CustomAdvancedUIManager(loginType, themeId, ...);
    configuration.setUIManager(advancedUIManager)
    
    UIManager themeManager = new ThemeUIManager(loginType, themeId);
    configuration.setUIManager(themeManager); class CustomAdvancedUIManager extends BaseUIManager {
        /*implementation here */
    }
    UIManager advancedUIManager = new CustomAdvancedUIManager(loginType, themeId, ...);
    configuration.setUIManager(advancedUIManager)
    
    UIManager themeManager = new ThemeUIManager(loginType, themeId);
    configuration.setUIManager(themeManager);

    Android偏好设置的API:

    最多可以为每位用户存储 100 个键/值对。键是 100 个字符以内的字符串,可以包含大小写字母、数字和下划线等字符。值是 1000 个字符以内的字符串。

    // Load all preferences for this account:
        AccountKit.getAccountPreferences().loadPreferences(new PrefsLoadListener());
        // Load a specific preference:
        AccountKit.getAccountPreferences().loadPreference("nickname", new SinglePrefLoadListener());
        // Set a preference:
        AccountKit.getAccountPreferences().setPreference("favoritecolor", "3b5998", new PrefSetListener());
        // Delete a preference:
        AccountKit.getAccountPreferences().loadPreference("timesincelastlogin ", new PrefDeleteListener());
    
        AccountKit.getAccountPreferences().loadPreferences(new PrefsLoadListener());
        // Load a specific preference:
        AccountKit.getAccountPreferences().loadPreference("nickname", new SinglePrefLoadListener());
        // Set a preference:
        AccountKit.getAccountPreferences().setPreference("favoritecolor", "3b5998", new PrefSetListener());
        // Delete a preference:
        AccountKit.getAccountPreferences().loadPreference("timesincelastlogin ", new PrefDeleteListener());
    
    private class PrefsLoadListener implements AccountPreferences.OnLoadPreferencesListener {
        public void onLoadPreferences(
            @Nullable Map<String, String> preferences,
            @Nullable AccountKitError error) {
          if (error != null) {
            // ... handle error appropriately ...
            return;
          }
          // You now have access to all existing user preferences in a Map
        }
      }
    
      private class SinglePrefLoadListener implements AccountPreferences.OnLoadPreferenceListener {
        public void onLoadPreference(String key, @Nullable String value, @Nullable AccountKitError error) {
          if (error != null) {
            // ... handle error appropriately ...
            return;
          }
          // ... use the delivered value and key ...
        }
      }
    
      private class PrefSetListener implements AccountPreferences.OnSetPreferenceListener {
        public void onSetPreference(String key, String value, @Nullable AccountKitError error) {
          if (error != null) {
            // ... handle error appropriately ...
            return;
          }
    
          // ... use the delivered value and key ...
        }
      }
    
      private class PrefDeleteListener implements AccountPreferences.OnDeletePreferenceListener {
        public void onDeletePreference(String key, @Nullable AccountKitError error) {
          if (error != null) {
            // ... handle error appropriately ...
            return;
          }
          // You have been notified that the value associated with "key" was deleted
        }
      } class PrefsLoadListener implements AccountPreferences.OnLoadPreferencesListener {
        public void onLoadPreferences(
            @Nullable Map<String, String> preferences,
            @Nullable AccountKitError error) {
          if (error != null) {
            // ... handle error appropriately ...
            return;
          }
          // You now have access to all existing user preferences in a Map
        }
      }
    
      private class SinglePrefLoadListener implements AccountPreferences.OnLoadPreferenceListener {
        public void onLoadPreference(String key, @Nullable String value, @Nullable AccountKitError error) {
          if (error != null) {
            // ... handle error appropriately ...
            return;
          }
          // ... use the delivered value and key ...
        }
      }
    
      private class PrefSetListener implements AccountPreferences.OnSetPreferenceListener {
        public void onSetPreference(String key, String value, @Nullable AccountKitError error) {
          if (error != null) {
            // ... handle error appropriately ...
            return;
          }
    
          // ... use the delivered value and key ...
        }
      }
    
      private class PrefDeleteListener implements AccountPreferences.OnDeletePreferenceListener {
        public void onDeletePreference(String key, @Nullable AccountKitError error) {
          if (error != null) {
            // ... handle error appropriately ...
            return;
          }
          // You have been notified that the value associated with "key" was deleted
        }
      }

     

     

     

    二,用户注册登录

    最总访问口令:

     

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        callbackManager = CallbackManager.Factory.create();
    
        accessTokenTracker = new AccessTokenTracker() {
            @Override
            protected void onCurrentAccessTokenChanged(
                AccessToken oldAccessToken,
                AccessToken currentAccessToken) {
                    // Set the access token using 
                    // currentAccessToken when it's loaded or set.
            }
        };
        // If the access token is available already assign it.
        accessToken = AccessToken.getCurrentAccessToken();
    }
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        callbackManager.onActivityResult(requestCode, resultCode, data);
    }
    
    @Override
    public void onDestroy() {
        super.onDestroy();
        accessTokenTracker.stopTracking();
    }
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        callbackManager = CallbackManager.Factory.create();
    
        accessTokenTracker = new AccessTokenTracker() {
            @Override
            protected void onCurrentAccessTokenChanged(
                AccessToken oldAccessToken,
                AccessToken currentAccessToken) {
                    // Set the access token using 
                    // currentAccessToken when it's loaded or set.
            }
        };
        // If the access token is available already assign it.
        accessToken = AccessToken.getCurrentAccessToken();
    }
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        callbackManager.onActivityResult(requestCode, resultCode, data);
    }
    
    @Override
    public void onDestroy() {
        super.onDestroy();
        accessTokenTracker.stopTracking();
    }

    追踪当前个人资料:

     

     

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        callbackManager = CallbackManager.Factory.create();
    
        profileTracker = new ProfileTracker() {
            @Override
            protected void onCurrentProfileChanged(
                    Profile oldProfile,
                    Profile currentProfile) {
                // App code
            }
        };
    }
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        callbackManager.onActivityResult(requestCode, resultCode, data);
    }
    
    @Override
    public void onDestroy() {
        super.onDestroy();
        profileTracker.stopTracking();
    }
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        callbackManager = CallbackManager.Factory.create();
    
        profileTracker = new ProfileTracker() {
            @Override
            protected void onCurrentProfileChanged(
                    Profile oldProfile,
                    Profile currentProfile) {
                // App code
            }
        };
    }
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        callbackManager.onActivityResult(requestCode, resultCode, data);
    }
    
    @Override
    public void onDestroy() {
        super.onDestroy();
        profileTracker.stopTracking();
    }

     

    三,Facebook分享

    Facebook的分享,有一个前提条件,就是应用必须已经安装,才能够分享。

    链接的分享:ShareLinkContent模型进行。

          截至 2017 年 4 月 18 日,图谱 API 版本 2.9 及更高版本不再支持下列参数。对于版本 2.8 及更低版本,这些参数将继续有效,直到 2017 年 7 月 17 日。
              contentTitle,表示链接中的内容的标题,imageURL,将在帖子中显示的缩略图的网址,内容的 contentDescription,通常为 2-4 个句子

    ShareLinkContent content = new ShareLinkContent.Builder()
            .setContentUrl(Uri.parse("https://developers.facebook.com"))
            .build();

    照片分享:小于12MB,客户端在7.0以上,SharePhotoContent模型进行。

     

    Bitmap image = ...
    SharePhoto photo = new SharePhoto.Builder()
            .setBitmap(image)
            .build();
    SharePhotoContent content = new SharePhotoContent.Builder()
            .addPhoto(photo)
            .build(); image = ...
    SharePhoto photo = new SharePhoto.Builder()
            .setBitmap(image)
            .build();
    SharePhotoContent content = new SharePhotoContent.Builder()
            .addPhoto(photo)
            .build();

     

    视频分享:小于12MB,ShareVideoContent模型进行

     

    Uri videoFileUri = ...
    ShareVideo = new ShareVideo.Builder()
            .setLocalUrl(videoUrl)
            .build();
    ShareVideoContent content = new ShareVideoContent.Builder()
            .setVideo(video)
            .build(); videoFileUri = ...
    ShareVideo = new ShareVideo.Builder()
            .setLocalUrl(videoUrl)
            .build();
    ShareVideoContent content = new ShareVideoContent.Builder()
            .setVideo(video)
            .build();

    多媒体分享:

     

    用户需要安装版本 71 或以上的原生 Android 版 Facebook 应用。
    照片大小必须小于 12MB。
    视频大小必须小于 12MB。
    用户每次可以分享最多包含 6 个照片和视频元素的内容。

     

    SharePhoto sharePhoto1 = new SharePhoto.Builder()
        .setBitmap(...)
        .build();
    SharePhoto sharePhoto2 = new SharePhoto.Builder()
        .setBitmap(...)
        .build();
    ShareVideo shareVideo1 = new ShareVideo.Builder()
        .setLocalUrl(...)
        .build();
    ShareVideo shareVideo2 = new ShareVideo.Builder()
        .setLocalUrl(...)
        .build();
    
    ShareContent shareContent = new ShareMediaContent.Builder()
        .addMedium(sharePhoto1)
        .addMedium(sharePhoto2)
        .addMedium(shareVideo1)
        .addMedium(shareVideo2)
        .build();
    
    ShareDialog shareDialog = new ShareDialog(...);
    shareDialog.show(shareContent, Mode.AUTOMATIC); sharePhoto1 = new SharePhoto.Builder()
        .setBitmap(...)
        .build();
    SharePhoto sharePhoto2 = new SharePhoto.Builder()
        .setBitmap(...)
        .build();
    ShareVideo shareVideo1 = new ShareVideo.Builder()
        .setLocalUrl(...)
        .build();
    ShareVideo shareVideo2 = new ShareVideo.Builder()
        .setLocalUrl(...)
        .build();
    
    ShareContent shareContent = new ShareMediaContent.Builder()
        .addMedium(sharePhoto1)
        .addMedium(sharePhoto2)
        .addMedium(shareVideo1)
        .addMedium(shareVideo2)
        .build();
    
    ShareDialog shareDialog = new ShareDialog(...);
    shareDialog.show(shareContent, Mode.AUTOMATIC);

    “赞”按钮
    “赞”按钮是用户与好友分享内容的快捷途径。轻触“赞”按钮即可为应用中的内容点“赞”,并将内容分享到 Facebook。

     

     

    LikeView likeView = (LikeView) findViewById(R.id.like_view);
    likeView.setObjectIdAndType(
        "https://www.facebook.com/FacebookDevelopers",
        LikeView.ObjectType.PAGE); likeView = (LikeView) findViewById(R.id.like_view);
    likeView.setObjectIdAndType(
        "https://www.facebook.com/FacebookDevelopers",
        LikeView.ObjectType.PAGE);

     

     

     

    “分享”按钮
    “分享”按钮将调用分享对话框。要添加“分享”按钮

     

    ShareButton shareButton = (ShareButton)findViewById(R.id.fb_share_button);
    shareButton.setShareContent(content); shareButton = (ShareButton)findViewById(R.id.fb_share_button);
    shareButton.setShareContent(content);

    分享对话框
    分享对话框会切换到原生 Android 版 Facebook 应用,并在发布帖子后将控制权交还您的应用。如果未安装 Facebook 应用,会自动回退到网页对话框。

     

     

         callbackManager = CallbackManager.Factory.create();
            shareDialog = new ShareDialog(this);
            // this part is optional
            shareDialog.registerCallback(callbackManager, new FacebookCallback<Sharer.Result>() { ... });
    = CallbackManager.Factory.create();
            shareDialog = new ShareDialog(this);
            // this part is optional
            shareDialog.registerCallback(callbackManager, new FacebookCallback<Sharer.Result>() { ... });
    
    if (ShareDialog.canShow(ShareLinkContent.class)) {
        ShareLinkContent linkContent = new ShareLinkContent.Builder()
                .setContentUrl(Uri.parse("http://developers.facebook.com/android"))
                .build();
        shareDialog.show(linkContent);
    } (ShareDialog.canShow(ShareLinkContent.class)) {
        ShareLinkContent linkContent = new ShareLinkContent.Builder()
                .setContentUrl(Uri.parse("http://developers.facebook.com/android"))
                .build();
        shareDialog.show(linkContent);
    }
    @Override
    protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        callbackManager.onActivityResult(requestCode, resultCode, data);
    }
    protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        callbackManager.onActivityResult(requestCode, resultCode, data);
    }

     

    话题标签:

    英文分享:

    自定义界面:

    分享链接:

    另外Facebook 同时也提供了分享,推送,Messager(基于Webhook),社交,邀请,广告,应用分析等开发者工具。

    其他的也没什么说的,这里提供一下官方给的例子吧:

           https://github.com/fbsamples/account-kit-samples-for-android

     

    展开全文
  • FaceBook登录接入

    万次阅读 2019-03-29 15:57:08
    官方文档Facebook登录接入Android官方文档创建应用首先去Facebook开发者平台注册一个开发者账户,这里需要翻墙,在后台添加一个自己的应用SDK集成SDK的集成方式有两种 Maven方式 在您的项目中,打开 your_app > ...

    ###官方文档
    Facebook登录接入Android官方文档
    ###创建应用
    首先去Facebook开发者平台注册一个开发者账户,这里需要翻墙,在后台添加一个自己的应用

    ###SDK集成
    SDK的集成方式有两种

    • Maven方式
    • 在您的项目中,打开 your_app > Gradle Scripts > build.gradle (Project),确保下列存储库都添加到 buildscript { repositories {}} 中
    jcenter() 
    
    • 在您的项目中,打开 your_app > Gradle Scripts > build.gradle (Module: app) 并将下列执行语句添加到 dependencies{} 部分,以便依赖于最新版的 Facebook 登录 SDK:
     implementation 'com.facebook.android:facebook-login:[4,5)'
    
    
    • Jar导入方式
      下载Facebook最新的SDK jar包放到项目的libs文件夹下。
      SDK下载地址是:Facebook SDK下载地址

    ###编辑资源和清单

    • 打开 /app/res/values/strings.xml 文件
    <string name="facebook_app_id">15477621189....</string>
    <string name="fb_login_protocol_scheme">fb15477621189....</string>
    
    • 打开 /app/manifest/AndroidManifest.xml 文件
      • 添加权限
    <uses-permission android:name="android.permission.INTERNET"/>
    
    • 在 application 元素中添加以下 meta-data 元素以及相应的Activity
    <meta-data android:name="com.facebook.sdk.ApplicationId" 
            android:value="@string/facebook_app_id"/>
        
        <activity android:name="com.facebook.FacebookActivity"
            android:configChanges=
                    "keyboard|keyboardHidden|screenLayout|screenSize|orientation"
            android:label="@string/app_name" />
        <activity
            android:name="com.facebook.CustomTabActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
                <data android:scheme="@string/fb_login_protocol_scheme" />
            </intent-filter>
        </activity>
    
    

    ###填入APP的包名
    在Facebook控制后台填入即可

    ###为应用提供开发和发布秘钥散列
    首先,需要三个工具:

    • keytool : JDK中默认已经有了
    • windows openssl函数库
    • keystore:debug.keystore 以及应用正式上线的keystore

    其次,利用命令行cmd去生成调试以及正式的keystore秘钥散列, cmd渠道JDK的目录下,输入一下命令,注意调整自己的各种路径,debug.keystore的密码默认是没有的,直接回车就好

    • 调试版秘钥散列
    keytool -exportcert -alias androiddebugkey -keystore "C:\Users\USERNAME\.android\debug.keystore" | "PATH_TO_OPENSSL_LIBRARY\bin\openssl" sha1 -binary | "PATH_TO_OPENSSL_LIBRARY\bin\openssl" base64
    
    
    • 正式版秘钥散列
    keytool -exportcert -alias YOUR_RELEASE_KEY_ALIAS -keystore YOUR_RELEASE_KEY_PATH | openssl sha1 -binary | openssl base64
    

    生成出来秘钥散列的是28个字符的字符串,类似于以下

    QvoiWD1LQEfDIrvczaq31WCJZjX=
    

    ###SDK的API使用

    • SDK的初始化登录回调,在onCreate()中调用
    callbackManager = CallbackManager.Factory.create();
            LoginManager.getInstance().registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
                @Override
                public void onSuccess(LoginResult loginResult) {
                    Log.e(TAG, "登录成功: " + loginResult.getAccessToken().getToken());
                    loginResult.getAccessToken().getApplicationId();
                    loginResult.getAccessToken().getUserId();
                }
    
                @Override
                public void onCancel() {
                    Log.e(TAG, "登录取消");
                }
    
                @Override
                public void onError(FacebookException error) {
                    Log.e(TAG, "登录错误");
                }
            });
    
    • 在你需要调用登录的地方调用登录接口
    LoginManager.getInstance().logInWithReadPermissions(MainActivity.this, Arrays.asList("public_profile"));
    
    • 在 onActivityResult 方法中调用 callbackManager.onActivityResult,通过 callbackManager 将登录结果传递至 LoginManager
          @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            callbackManager.onActivityResult(requestCode, resultCode, data);
            super.onActivityResult(requestCode, resultCode, data);
        }
    

    这样一个简单的Facebook登录客户端API已经完成了,如果需要服务端校验,各家的校验方式都不一样,可以参考访问口令

    ###应用测试

    • 测试手机:需要翻墙
      • 需要有google play服务,可以到各大应用商店下载:谷歌安装器
      • google play商店下载Facebook app
    • 将代买debug安装到手机运行测试

    ###注意事项

    • 将自己的debug.keystore生成散列秘钥配置到Facebook控制后台,要不然debug出来的app安装到手机会不可用
    • 注意自己的申请参数正确配置到:/app/res/values/strings.xml中
    • 如果在Facebook控制后台配置了包名,请确保自己应用的包名和Facebook配置的一样

    ###常见问题

    facebook onErrorSERVER_ERROR: [code] 1675030 [message]: 执行查询时出错。 [extra]:

    解答:因为该Facebook 账号不是测试账号

    展开全文
  • Facebook注册机_Facebook账号注册_Csharp代码示例_.Net代码

    【Facebook注册机_Facebook账号注册_Csharp代码示例_.Net代码】

    朋友叫了很久帮忙写,无奈今天花时间研究下。。。。

    下面只是一个简单示例,

    里面我写有一些类,对于写注册机之类的,或许有帮助哟!!


    ======================================



    注册是成功了,可登录发现跳出手机验证。。。。



    部分代码:


    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Windows.Forms;
    
    namespace Register
    {
        public partial class Form1 : Form
        {
    
            public Form1()
            {
                InitializeComponent();
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                button1.Enabled = false;
                Notify("*********开始**********", 2);
                //设置参数
                string xing = EnVon.Helper.ChineseHelper.GetXing();
                string ming = EnVon.Helper.ChineseHelper.GetMing(2);
                string email = Helper.ChineseHelper.GetPinYin(xing + ming).ToLower() + Helper.StringHelper.GetEmailDomain();
                string password = EnVon.Helper.StringHelper.RndString(4) + EnVon.Helper.StringHelper.RndString(5, 1);
                string birYear = Helper.StringHelper.RndNumberS(1980, 1996);
                string birMonth = Helper.StringHelper.RndNumberS(1, 13);
                string birDay = Helper.StringHelper.RndNumberS(1, 29);
                string retData = string.Empty;
                //创建对象
                Facebook.Register reg = new Facebook.Register()
                {
                    birthday_day = birDay, //生日日
                    birthday_month = birMonth, //生日月
                    birthday_year = birYear, //生日年
                    firstname = ming, //名字
                    lastname = xing, //姓
                    reg_email__ = email, //邮箱
                    reg_email_confirmation__ = email, //确认邮箱
                    reg_passwd__ = password //密码
                };
                //打开注册页
                Notify("打开注册页。。。");
                int retB = reg.OpenRegPage();
                if (retB == 0)
                {
                    Thread.Sleep(200);
                    Notify("提交注册表单。。。");
                    //提交注册
                    retB = reg.PostForm(out retData);
                    if (retB == 0)
                    {
                        Notify("恭喜,注册成功!!");
                        Notify("-----------------------------");
                        Notify("姓名:" + xing + ming);
                        Notify("邮箱:" + email);
                        Notify("密码:" + password);
                        Notify("生日:" + birYear + "-" + birMonth + "-" + birDay);
                        Notify("-----------------------------");
                    }
                    else if (retB == 1)
                    {
                        Notify("注册失败!");
                        Notify("失败原因:邮箱已注册过!");
                    }
                    else
                    {
                        Notify("注册失败!");
                        Notify("失败原因:" + reg.GetErrMessage(retData));
                    }
                    rtxtData.Text = retData;
                }
                else
                {
                    Notify("打开注册页失败!");
                }
                Notify("*********完毕**********");
                button1.Enabled = true;
            }
    
    
            private void button2_Click(object sender, EventArgs e)
            {
            }
    
    
            private void Notify(string str, int mode = 8)
            {
                if (mode == 8)
                {
                    rtxtMain.Text += DateTime.Now + " " + str + "\r\n";
                }
                else
                {
                    rtxtMain.Text = DateTime.Now + " " + str + "\r\n";
                }
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                this.Text = "Facebook账号注册示例";
            }
    
    
        }
    }
    

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace Facebook
    {
        /// <summary>
        /// Facebook账号注册
        /// </summary>
        public class Register
        {
            private Random RND = new Random();
            private EnVon.HttpRequest http = null;
    
            #region 注册的参数
            public string lastname { get; set; }
            public string firstname { get; set; }
            public string reg_email__ { get; set; }
            public string reg_email_confirmation__ { get; set; }
            public string reg_passwd__ { get; set; }
            public string birthday_year { get; set; }
            public string birthday_month { get; set; }
            public string birthday_day { get; set; }
            private string lsd { get; set; }
            private string sex
            {
                get { return string.Empty + RND.Next(1, 3); }
                set { }
            }
            private string referrer { get; set; }
            private string asked_to_login { get; set; }
            private string terms { get; set; }
            private string ab_test_data { get; set; }
            private string contactpoint_label { get; set; }
            private string locale { get; set; }
            private string abtest_registration_group { get; set; }
            private string reg_instance { get; set; }
            private string captcha_persist_data { get; set; }
            private string captcha_session { get; set; }
            private string extra_challenge_params { get; set; }
            private string recaptcha_type { get; set; }
            private string captcha_response { get; set; }
            private string ignore { get; set; }
            private string __user { get; set; }
            private string __a { get; set; }
            private string __dyn { get; set; }
            private string __req { get; set; }
            private string __rev { get; set; } 
            #endregion
    
    
            public Register()
            {
                __req = "5";
                //__dyn = "7wiXwNAwsUKEkzoynFwh8";
                __a = "1";
                __user = "0";
                ignore = "captcha";
                captcha_response = "";
                recaptcha_type = "password";
                abtest_registration_group = "1";
                locale = "zh_CN";
                contactpoint_label = "email_only";
                terms = "on";
                asked_to_login = "0";
                referrer = "";
                http = new EnVon.HttpRequest();
                http.UserAgent = "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.3; WOW64; Trident/7.0)";
            }
    
            /// <summary>
            /// 打开注册页并获取部分参数
            /// </summary>
            /// <returns></returns>
            public int OpenRegPage()
            {
                string url = "https://www.facebook.com/";
                string data = http.GetData(url, "utf-8");
                if (data.Length > 100)
                {
                    var arr = Helper.StringHelper.MidMulti(data, "<input", ">");
                    __rev = Helper.StringHelper.Mid(data, "\"revision\":", ",");
                    //ab_test_data = "AAAP/P/f/fAAPAAAfAAPfAAAPAAAfAPAAAAAAAAAO/VMEAACCCOBBM";//???
                    captcha_persist_data = GetInputValue(arr, "captcha_persist_data");
                    captcha_session = GetInputValue(arr, "captcha_session");
                    extra_challenge_params = GetInputValue(arr, "extra_challenge_params");
                    lsd = GetInputValue(arr, "lsd");
                    reg_instance = GetInputValue(arr, "reg_instance");
                    return 0;
                }
                return 1;
            }
    
            /// <summary>
            /// 提交注册表单
            /// </summary>
            /// <returns></returns>
            public int PostForm(out string html)
            {
                int retB = -1;
                string pUrl = "https://www.facebook.com/ajax/register.php";
                string pRef = "https://www.facebook.com/";
                string pData = string.Empty;
                //拼接pData
                Dictionary<string, string> dicParams = new Dictionary<string, string>();
                dicParams.Add("__a", __a);
                dicParams.Add("__dyn", __dyn);
                dicParams.Add("__req", __req);
                dicParams.Add("__rev", __rev);
                dicParams.Add("__user", __user);
                dicParams.Add("ab_test_data", ab_test_data);
                dicParams.Add("abtest_registration_group", abtest_registration_group);
                dicParams.Add("asked_to_login", asked_to_login);
                dicParams.Add("birthday_day", birthday_day);
                dicParams.Add("birthday_month", birthday_month);
                dicParams.Add("birthday_year", birthday_year);
                dicParams.Add("captcha_persist_data", captcha_persist_data);
                dicParams.Add("captcha_response", captcha_response);
                dicParams.Add("captcha_session", captcha_session);
                dicParams.Add("contactpoint_label", contactpoint_label);
                dicParams.Add("extra_challenge_params", extra_challenge_params.Replace("&", "&"));
                dicParams.Add("firstname", firstname);
                dicParams.Add("ignore", ignore);
                dicParams.Add("lastname", lastname);
                dicParams.Add("locale", locale);
                dicParams.Add("lsd", lsd);
                dicParams.Add("recaptcha_type", recaptcha_type);
                dicParams.Add("referrer", referrer);
                dicParams.Add("reg_email__", reg_email__);
                dicParams.Add("reg_email_confirmation__", reg_email_confirmation__);
                dicParams.Add("reg_instance", reg_instance);
                dicParams.Add("reg_passwd__", reg_passwd__);
                dicParams.Add("sex", sex);
                dicParams.Add("terms", terms);
                foreach (string item in dicParams.Keys)
                {
                    pData += (pData.Length > 0 ? "&" : "") + item + "=" + Helper.StringHelper.UrlEncode(dicParams[item]);
                }
                //提交数据
                html = http.PostData(pUrl, pData, "utf-8", pRef);
                if (html.IndexOf("registration_succeeded\":true") > 0)
                {
                    if (html.IndexOf("redirect\":\"\\/register\\/confirm.php") > 0)
                    {
                        retB = 1;//邮箱已注册过
                    }
                    else { retB = 0;/*注册成功*/ }
                }
                return retB;
            }
    
            /// <summary>
            /// 取错误提示信息
            /// </summary>
            /// <param name="retData"></param>
            /// <returns></returns>
            public string GetErrMessage(string retData)
            {
                string str = EnVon.Helper.StringHelper.UnicodeDecode(retData);
                str = Helper.StringHelper.FiltHtml(str);
                str = Helper.StringHelper.Mid(str, "{\"__html\":\"", "\"},\"error_code");
                return str;
            }
    
    
            private string GetInputValue(List<string> list, string name)
            {
                string str = string.Empty;
                foreach (string item in list)
                {
                    if (item.IndexOf("name=\"" + name + "\"") > 0)
                    {
                        str = Helper.StringHelper.Mid(item,"value=\"","\"" );
                        break;
                    }
                }
                return str;
            }
    
    
        }
    }
    


    使用VS2013编写,源码下载:

    http://download.csdn.net/detail/envon123/7327619


    =========================================================

    END


    
    展开全文
  • facebook

    2020-07-29 14:19:48
    NULL 博文链接:https://timerbin.iteye.com/blog/2029725
  • FaceBook数据采集——模拟登录

    万次阅读 2016-11-07 19:30:09
    获取FaceBook cookie值的两种方法,一种是模拟登陆的方法,另一种使用selenium模拟手工操作。

    前言


    本科的毕业设计有做facebook的数据采集工作。在做的过程中,发现网上现成的资料较少,所以将我的解决办法分享出来,希望大家一起讨论并提出宝贵意见。

    Facebook数据采集可以通过调用API,但是API获取数据较为混乱,没法有效的将数据组织在一起,所以就放弃了这种办法,改为采用网络爬虫的方式,但是网络爬虫个也存在各种问题。

    在临近毕业的两周,我尽量每两天更新一篇文章,讨论其中一个问题的解决办法。

    今天讨论的是模拟登录问题。

    总的来说,使用python模拟登陆有两大类方法,一种是发送请求数据包,模拟数据交互的过程;另一种办法是使用selenium包,模拟用户的手工操作。

    数据交互的方法


    数据交互的方法的代码量比较多,但是运行起来速度要比使用selenium包快的多,也更容易控制。但是网上有人说,FaceBook会时常变动登陆过程中需要post的值,所以没有办法长期使用固定的代码。据我观察,近一个月的时间内,FaceBook的登陆过程没有发生变化。。。所以,自己看着办吧。反而是使用selenium包的方法有着很大的不确定性,具体情况放在下面讨论。

    Facebook的登陆主要有三步,过程如下:

    step 1

    进入https://www.facebook.com,获取set-cookies值fr,下一步需要post的值lsd、lgnrnd、lgnjs,这三个值在html中均放在input标签下,且type均为‘hidden’,如下:

    <input type="hidden" name="lsd" value="AVpI6yeG" autocomplete="off" />
    <input type="hidden" name="lgnrnd" value="171524_eEMy" />
    <input type="hidden" id="lgnjs" name="lgnjs" value="n" /></span>

    使用正则语句将value值提取出即可,Cookie值使用cookiejar存储即可,方便下一步的使用。代码如下:

    def login_first_step(self):
            sent_url = 'https://www.facebook.com'
            request = urllib2.Request(url=sent_url,headers=self.facebook_header)
            content=self.opener.open(request)
            html = content.read()
            lsd=lgndim=lgnjs=lgnrnd=''
    
            # 查找lsd
            reg = r'<input type="hidden" name="lsd" value="([A-Za-z0-9]*)" autocomplete="off" />'
            m = re.compile(reg)
            search = re.search(m,html)
            if search:
                lsd = search.group(1)
    
            # 查找lgndim lgndim可能为空
            reg = r'<input type="hidden" autocomplete="off" name="lgndim" value="([A-Za-z0-9]*)"'
            m = re.compile(reg)
            search = re.search(m,html)
            if search:
                lgndim = search.group(1)
    
            # 查找lgnrnd
            reg = r'<input type="hidden" name="lgnrnd" value="([A-Za-z0-9]*_[A-Za-z0-9]*)" />'
            m = re.compile(reg)
            search = re.search(m,html)
            if search:
                lgnrnd = search.group(1)
    
            # 查找lgnjs
            reg = r'<input type="hidden" id="lgnjs" name="lgnjs" value="([A-Za-z0-9]*)" />'
            m = re.compile(reg)
            search = re.search(m,html)
            if search:
                lgnjs = search.group(1)
            
            #设置第二步中要post的值
            self.login_post_values = 'lsd='+lsd+'&email='+self.email+'&pass='+self.password+\
                                     '&persistent=&default_persistent=1&timezone=&lgndim=&lgnrnd='\
                                     +lgnrnd+'&lgnjs='+lgnjs+'&locale=zh_CN&next=https%3A%2F%2Fwww.facebook.com%2F'
    
            print '-------------------------------------------'
            print 'lsd:',lsd
            print 'lgndim:',lgndim
            print 'lgnjs:',lgnjs
            print 'lgnrnd:',lgnrnd
            print self.cj
            for key in self.cj:
                print key.name,':',key.value
            print '-------------------------------------------'</span>


    step 2


    进入https://www.facebook.com/login.php?login_attempt=1&lwv=110,在header的cookies中提交fr的值,在post中提交下面八个值,其中:lsd、email、pass、persistent、default_persistent、timezone、lgndim、lgnrnd、lgnjs、locale、next。这些值必须按照指定顺序提交,这个按顺序提交纠结了我一天。。。。其中email是登陆的用户名,pass是密码。Local是地区,比如“zh_CN”。Next为https://www.facebook.com/。注意发送前使用urllib.urlencode(values)函数对post的值进行url编码。其输入是一个字典,输出是一段字符串。Python的urllib2包中处理header数据时,是以字典类型作为输入的,所以不需要进行url编码,这个小问题也需要注意,否则会浪费很多时间。
    def login_second_step(self):
            sent_url = 'https://www.facebook.com/login.php?login_attempt=1&lwv=110'
            request = urllib2.Request(url=sent_url,headers=self.facebook_header,data=self.login_post_values)
            content=self.opener.open(request)
            print '-------------------------------------------'
            for key in self.cj:
                print key.name,':',key.value
            print '-------------------------------------------'</span>
    这一步的response是302重定向报文,python会自动向新目标https://www.facebook.com/发送一个新的请求,但是这个请求没有带上我们获取的cookie值。为了使得重定向报文得到新的cookie值,需要自己编写http_error_302()方法,参考了下面这篇博客http://www.hawkwithwind.net/blog/2013/08/13/python-urllib2-%E9%87%8D%E5%AE%9A%E5%90%91%E6%97%B6%E8%8E%B7%E5%8F%96cookie/
    首先我们要自己编写一个遇到302重定向时的解决办法,在这里我的做法比较粗暴,手工处理cookie值,并将新cookie值添加到请求的头部,代码如下:
    class RedirectHandler(urllib2.HTTPRedirectHandler):
        def http_error_302(self,req,fp,code,msg,headers):
            print '############ GOT 302 ###############'
            cookiemap = {}
            setcookie = str(headers["Set-Cookie"])
            cookieTokens = ["Domain","Expires", "Path", "Max-Age",'path','domain']
            tokens = setcookie.split(";")
            for cookie in tokens:
                cookie = cookie.strip()
                if cookie.startswith("Expires="):
                    cookies = cookie.split(",", 2)
                    if len(cookies) > 2:
                        cookie = cookies[2]
                        cookie = cookie.strip()
                else :
                    cookies = cookie.split(",", 1)
                    if len(cookies) > 1:
                        cookie = cookies[1]
                        cookie = cookie.strip()
                namevalue = cookie.split("=", 1)
                if len(namevalue) > 1:
                    name = namevalue[0]
                    value = namevalue[1]
                    if name not in cookieTokens:
                        cookiemap[name] = value
            print cookiemap
            str_cookie = ''
            for key in cookiemap:
                str_cookie = str_cookie + key + '=' + cookiemap[key] + '; '
            str_cookie = str_cookie[:-2]
            print str_cookie
            req.add_header("Cookie", str_cookie)<span style="white-space:pre">	</span>#设置新的cookie值
            return urllib2.HTTPRedirectHandler.http_error_302(self, req, fp, code, msg, headers)</span>
    然后,需要在urllib2包中提交请求的opener中添加我们的302处理方法,代码如下:
    opener = urllib2.build_opener(httpHandler, httpsHandler,RedirectHandler,
                                          urllib2.HTTPCookieProcessor(self.cj))</span>
    至此,302重定向问题就解决完了,当python检测到收到重定向页面后,会执行我们编写的出错处理方法。

    step 3


    有了前面的铺垫,第三步就简单了很多,直接访问facebook的个人主页即可。
    在这里不得不提一下cookiejar这个小工具,cookiejar来源于cookielib包。这个小工具能够自动的存储已经获取的cookie值(即response头部的set-cookie值),并在下一次访问时添加上这些cookie值。当然,我们也能够自己增删改查cookiejar中的内容,使用起来很方便。否则我们需要自己动手写处理cookie的代码,非常浪费时间。
    def login_third_step(self):
            sent_url = 'https://www.facebook.com'
            request = urllib2.Request(url=sent_url,headers=self.facebook_header)
            content=self.opener.open(request)
            print '-------------------------------------------'
            print content.read()
            print '-------------------------------------------'</span>
    到这里,我们已经登录到了facebook,但是只是到了欢迎页面,并查看不了“朋友圈”,因为此时,cookie中少了一个值,“datr”,这个值在step 3的response的数据中,使用相同的办法找到并提交即可,所以需要对step 3进行修改:
        def login_third_step(self):
            sent_url = 'https://www.facebook.com'
            request = urllib2.Request(url=sent_url,headers=self.facebook_header)
            content=self.opener.open(request)
            # print content.read()
            tmp_html = content.read()
            #查找datr
            reg = r'"_js_datr","([A-Za-z0-9]*)"'
            m = re.compile(reg)
            search = re.search(m,tmp_html)
            datr = ''
            if search:
                datr = search.group(1)
            print '-------------------------------------------'
            print 'datr: ',datr
            self.cj.set_cookie(cookielib.Cookie(
                version=0,
                name='datr',
                value=datr,
                port=None,
                port_specified=False,
                domain=".facebook.com",
                domain_specified=True,
                domain_initial_dot=False,
                path="/",
                path_specified=True,
                secure=False,
                expires=None,
                discard=False,
                comment=None,
                comment_url=None,
                rest=None
            ))
    然后把数据再次提交即可:
    def login_fourth_step(self):
            sent_url = 'https://www.facebook.com'
            request = urllib2.Request(url=sent_url,headers=self.facebook_header)
            content=self.opener.open(request)
            print '-------------------------------------------'
            print '               getting html        '
            # print content.read()
            self.html = content.read()
            print '-------------------------------------------'

    至此,模拟登陆就完成了,至于解析数据,放在下一篇文章再讨论。整个模拟登陆代码如下:
    # -*- coding:gb2312 -*-
    __author__ = 'HYDT'
    
    import urllib2
    import re
    import cookielib
    
    class RedirectHandler(urllib2.HTTPRedirectHandler):
        def http_error_302(self,req,fp,code,msg,headers):
            print '############ GOT 302 ###############'
            cookiemap = {}
            setcookie = str(headers["Set-Cookie"])
            cookieTokens = ["Domain","Expires", "Path", "Max-Age",'path','domain']
            tokens = setcookie.split(";")
            for cookie in tokens:
                cookie = cookie.strip()
                if cookie.startswith("Expires="):
                    cookies = cookie.split(",", 2)
                    if len(cookies) > 2:
                        cookie = cookies[2]
                        cookie = cookie.strip()
                else :
                    cookies = cookie.split(",", 1)
                    if len(cookies) > 1:
                        cookie = cookies[1]
                        cookie = cookie.strip()
                namevalue = cookie.split("=", 1)
                if len(namevalue) > 1:
                    name = namevalue[0]
                    value = namevalue[1]
                    if name not in cookieTokens:
                        cookiemap[name] = value
            print cookiemap
            str_cookie = ''
            for key in cookiemap:
                str_cookie = str_cookie + key + '=' + cookiemap[key] + '; '
            str_cookie = str_cookie[:-2]
            print str_cookie
            req.add_header("Cookie", str_cookie)
            return urllib2.HTTPRedirectHandler.http_error_302(self, req, fp, code, msg, headers)
    
    class get_html():
        email = '%2B<span style="font-family: Arial, Helvetica, sans-serif;">86185xxxxxxxx</span><span style="font-family: Arial, Helvetica, sans-serif;">'  #用户名 +86185xxxxxxxx 注意加号改成url编码 %2B</span>
        password = ''       #密码
    
        cj = cookielib.CookieJar()
        login_post_values = ''
        html = ''
    
        facebook_header = {
            "Connection":"close",
            "Cache-Control":"max-age=0",
            "Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
            "Origin":"https://www.facebook.com",
            "Upgrade-Insecure-Requests":" 1",
            "User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) "
                         "Chrome/45.0.2454.101 Safari/537.36",
            "Content-Type":"application/x-www-form-urlencoded",
            "Referer":"https://www.facebook.com/",
            "Accept-Language":"zh-CN,zh;q=0.8"
        }
        opener = urllib2.build_opener()
    
        def get_opener(self):
            # self.cj = self.cj.clear()
            httpHandler = urllib2.HTTPHandler(debuglevel=1)
            httpsHandler = urllib2.HTTPSHandler(debuglevel=1)
            opener = urllib2.build_opener(httpHandler, httpsHandler,RedirectHandler,
                                          urllib2.HTTPCookieProcessor(self.cj))
            return opener
    
        def login_first_step(self):
            sent_url = 'https://www.facebook.com'
            request = urllib2.Request(url=sent_url,headers=self.facebook_header)
            content=self.opener.open(request)
            html = content.read()
            lsd=lgndim=lgnjs=lgnrnd=''
    
            # 查找lsd
            reg = r'<input type="hidden" name="lsd" value="([A-Za-z0-9]*)" autocomplete="off" />'
            m = re.compile(reg)
            search = re.search(m,html)
            if search:
                lsd = search.group(1)
    
            # 查找lgndim lgndim可能为空
            reg = r'<input type="hidden" autocomplete="off" name="lgndim" value="([A-Za-z0-9]*)"'
            m = re.compile(reg)
            search = re.search(m,html)
            if search:
                lgndim = search.group(1)
    
            # 查找lgnrnd
            reg = r'<input type="hidden" name="lgnrnd" value="([A-Za-z0-9]*_[A-Za-z0-9]*)" />'
            m = re.compile(reg)
            search = re.search(m,html)
            if search:
                lgnrnd = search.group(1)
    
            # 查找lgnjs
            reg = r'<input type="hidden" id="lgnjs" name="lgnjs" value="([A-Za-z0-9]*)" />'
            m = re.compile(reg)
            search = re.search(m,html)
            if search:
                lgnjs = search.group(1)
    
            #设置第二步中要post的值
            self.login_post_values = 'lsd='+lsd+'&email='+self.email+'&pass='+self.password+\
                                     '&persistent=&default_persistent=1&timezone=&lgndim=&lgnrnd='\
                                     +lgnrnd+'&lgnjs='+lgnjs+'&locale=zh_CN&next=https%3A%2F%2Fwww.facebook.com%2F'
    
            print '-------------------------------------------'
            print 'lsd:',lsd
            print 'lgndim:',lgndim
            print 'lgnjs:',lgnjs
            print 'lgnrnd:',lgnrnd
            print self.cj
            for key in self.cj:
                print key.name,':',key.value
            print '-------------------------------------------'
    
        def login_second_step(self):
            sent_url = 'https://www.facebook.com/login.php?login_attempt=1&lwv=110'
            request = urllib2.Request(url=sent_url,headers=self.facebook_header,data=self.login_post_values)
            content=self.opener.open(request)
            print '-------------------------------------------'
            for key in self.cj:
                print key.name,':',key.value
            print '-------------------------------------------'
    
        def login_third_step(self):
            sent_url = 'https://www.facebook.com'
            request = urllib2.Request(url=sent_url,headers=self.facebook_header)
            content=self.opener.open(request)
            # print content.read()
            tmp_html = content.read()
            #查找datr
            reg = r'"_js_datr","([A-Za-z0-9]*)"'
            m = re.compile(reg)
            search = re.search(m,tmp_html)
            datr = ''
            if search:
                datr = search.group(1)
            print '-------------------------------------------'
            print 'datr: ',datr
            self.cj.set_cookie(cookielib.Cookie(
                version=0,
                name='datr',
                value=datr,
                port=None,
                port_specified=False,
                domain=".facebook.com",
                domain_specified=True,
                domain_initial_dot=False,
                path="/",
                path_specified=True,
                secure=False,
                expires=None,
                discard=False,
                comment=None,
                comment_url=None,
                rest=None
            ))
    
        def login_fourth_step(self):
            sent_url = 'https://www.facebook.com'
            request = urllib2.Request(url=sent_url,headers=self.facebook_header)
            content=self.opener.open(request)
            print '-------------------------------------------'
            print '               getting html        '
            # print content.read()
            self.html = content.read()
            print '-------------------------------------------'
    
    
    
        def get_proxy(self):
            proxy = {'http':'http://127.0.0.1:1080'}
            proxy_support = urllib2.ProxyHandler(proxy)
            opener = urllib2.build_opener(proxy_support)
            urllib2.install_opener(opener)
            print "#########Open Proxy!##########"
    
        def __init__(self):
            self.get_proxy()
            self.cj = cookielib.CookieJar()
            self.opener = self.get_opener()
            self.login_first_step()
            self.login_second_step()
            self.login_third_step()
            self.login_fourth_step()
    
    # get_html()


    模拟手工操作的方法


    这种方法就十分简单了,直接上代码。
    def get_cookies(self):
            print "=============================="
            print "       Geting Cookies!        "
            print "=============================="
            #选择浏览器
            browser = webdriver.Firefox()   
            # browser.implicitly_wait(10)
            # browser.set_window_size(0,0)
            #访问facebook网页
            browser.get('https://www.facebook.com/')    
            #输入账户密码
            browser.find_element_by_id('email').clear() 
            browser.find_element_by_id('email').send_keys(self.email)
            browser.find_element_by_id('pass').clear()
            browser.find_element_by_id('pass').send_keys(self.password)
            #模拟点击登录按钮,两种不同的点击方法。。。
            try:    
                browser.find_element_by_xpath('//button[@id="loginbutton"]').send_keys(Keys.ENTER)
            except:
                browser.find_element_by_xpath('//input[@tabindex="4"]').send_keys(Keys.ENTER)
            # time.sleep(10)
            browser.find_element_by_xpath('//a[@href="https://www.facebook.com/?ref=logo"]').send_keys(Keys.ENTER)
    
            # browser.file_detector_context('Facebook').send_keys(Keys.ENTER)
            #获取cookie
            cookies = browser.get_cookies() 
            #关闭浏览器
            browser.close() </span>
    
    


    总结


    在这篇博文中,介绍了两种模拟登陆的方法,一种是模拟数据交互过程,该方法的优点在于执行速度快,相对较为稳定,缺点是开发时间长。模拟手工操作的方法正好相反,运行速度较慢,但开发速度极快。根据获取的cookie值可以看出来,一次模拟登陆的cookie值,有效期是三个月。所以,该程序三个月运行一次即可,那么运行速度慢点完全可以接受。所以,在现实的工程中,到底使用哪种方法,可以依据情况而定。

    展开全文
  • Facebook 登录和分享

    千次阅读 2019-01-29 16:02:59
    Facebook 登录和分享
  • 整理了Facebook的直播开发教程 以及网络抓包 整理了Facebook的直播开发教程 以及网络抓包
  • 转载自本人独立博客:...Clément Mihailescu是YouTube的一名视频博主,他现在正在创业,创办了一个叫algoexpert的网站(类似leetcode,在线做算法题的那种),他也是google和facebook的前雇...
  • 先上图,Facebook登录会提供
  • 关注并标星星CSDN云计算极客头条:速递、最新、绝对有料。这里有企业新动、这里有业界要闻,打起十二分精神,紧跟fashion你可以的!每周两次,打卡即read更快、更全了...
  • FaceBook客户端

    2020-07-04 09:59:30
    Facebook(脸书)是美国的一个社交网络服务网站 ,创立于2004年2月4日,总部位于美国加利福尼亚州门洛帕克,2012年3月6日发布Windows版桌面聊天软件Facebook Messenger [1] 。主要创始人马克·扎克伯格。 Facebook是...
  • facebook数据爬取

    千次阅读 2017-11-28 17:24:52
    Python爬取Facebook请求数据需要的字段:app_id ,access_token 1、app_id 及账户id 2、access_token 获取:  1、facebook开发者账户 products添加 Marketing API 2、(setting 高级 添加Account IDs (不知道必不必要...
  • 本文现已搬迁至: https://blog.csdn.net/NRatel/article/details/84241100 此博客废弃,我的新CSDN账号:https://blog.csdn.net/NRatel/
  • facebook分享(含图片)

    万次阅读 2016-09-24 21:41:53
    一、查看当前URL下facebook信息情况 Open Graph Object Debugger: https://developers.facebook.com/tools/debug/og/object/ Show existing scrape information:查看已配置的facebook信息 Fetch new scrape ...
  • 如何注销Facebook账户

    千次阅读 2015-11-12 11:14:17
    在浏览器键入地址:https://ssl.facebook.com/help/contact.php?show_form=delete_account,会转入以下界面 点提交后,再输入密码和验证码; 系统出现如下提示,并同时发一封...
  • Unity3D 关于Facebook SDK接入方法(一)

    万次阅读 2016-11-28 10:27:18
    1.下载及安装Facebook SDK 步骤一:前往https://developers.facebook.com/?advanced_app_create=true添加应用,这里我们以安卓为例。 步骤二:输入现用应用的名称或新建应用 步骤三:在开发者页面右...
  • facebook login 申请 app_id 和 app_secret

    万次阅读 2017-07-27 18:13:02
    https://developers.facebook.com 在Facebook Login的右边点击Get Start 勾选选项,填写登录成功回调的url地址。 保存成功后,点击左侧的Dashborad,查看app id 和 app secret代码。 到...
  • 加86,立刻能收到…
  • facebook关注和加好友的区别?

    万次阅读 2018-10-11 14:21:01
    站外,听起来挺复杂,其实无外乎就是从和亚马逊这个巨头玩变成了和Google还有Facebook这两个巨头玩。就Google而言,与亚马逊的适配性其实并不大,玩的不好很容易水土不服。但是Facebook是能够直接和亚马逊形成连接的...
  • [转]Facebook主要后台技术

    千次阅读 2011-05-24 17:53:00
    Facebook主要后台技术
1 2 3 4 5 ... 20
收藏数 220,645
精华内容 88,258
关键字:

facebook