使用 python 请求登录 Facebook

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21928368/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 23:53:26  来源:igfitidea点击:

Login to Facebook using python requests

pythonfacebookfacebook-loginpython-requests

提问by alexryabkov

I'm trying to find a way to automatically login to Facebook without browser using Python. I experimented with "requests" lib. Tried several ways:

我正在尝试找到一种使用 Python 无需浏览器即可自动登录 Facebook 的方法。我尝试了“请求”库。尝试了几种方法:

URL = 'http://m.facebook.com'
requests.get(URL, auth = ('[email protected]', 'mypassword'))

...

...

form_data = {'email': '[email protected]',
             'pass' : 'mypassword'
            }
requests.post(URL, data = form_data)

...

...

requests.post(URL + '[email protected]&pass=mypassword')

The last method fills "email" box on a page but "pass" box remains empty...

最后一种方法填充页面上的“电子邮件”框,但“传递”框保持为空...

Could someone help me with this please? Is it possible to emulate FB login using requests?

有人可以帮我吗?是否可以使用请求模拟 FB 登录?

Thanks!

谢谢!

采纳答案by Lukasa

You need to send a complete form. The easiest way to find out what Facebook expects is to use something like Google Chrome's developer toolsto monitor your web requests.

您需要发送一份完整的表格。了解 Facebook 期望什么的最简单方法是使用类似Google Chrome 的开发人员工具来监控您的网络请求。

To make your life easier I've monitored my own login on Facebook, and reproduced it below (with private information redacted, obviously) with the unimportant information stripped:

为了让您的生活更轻松,我监控了我自己在 Facebook 上的登录信息,并在下面复制了它(显然已删除了私人信息),并删除了不重要的信息:

Request URL:https://m.facebook.com/login.php?refsrc=https%3A%2F%2Fm.facebook.com%2F&refid=8
Request Method:POST

Form Data:
    lsd:AVqAE5Wf
    charset_test:,′,,′,水,Д,?
    version:1
    ajax:0
    width:0
    pxr:0
    gps:0
    m_ts:1392974963
    li:cxwHUxatQiaLv1nZEYPp0aTB
    email:...
    pass:...
    login:Log In

As you can see, the form contains a lot of fields. All of these need to be provided to allow you to log in. Email and password will be provided by your code. The rest of the fields actually have their values set by the HTML that Facebook serves you. This means, to emulate a browser login you need to perform the following steps:

如您所见,表单包含很多字段。所有这些都需要提供才能让您登录。电子邮件和密码将由您的代码提供。其余字段的值实际上由 Facebook 为您提供的 HTML 设置。这意味着,要模拟浏览器登录,您需要执行以下步骤:

  1. Do a GET to the login page (https://m.facebook.com/)
  2. Use a HTML parsing library (e.g. BeautifulSoup) to parse the HTML and find the default values of the form fields.
    • The default values are all in <input>HTML elements below the #login_formelement. You'll want to find them by name (e.g. charset_test) and then pull out their valueattribute.
    • Working out how to do this is outside the scope of this answer, so I'm not going to go into it.
  3. Combine the default values of the form fields with your email and password, like so:

    data = {
        'lsd': lsd,
        'charset_test': csettest, 
        'version': version,
        'ajax': ajax,
        'width': width,
        'pxr': pxr,
        'gps': gps,
        'm_ts': mts,
        'li': li,
    }
    data['email'] = email
    data['pass'] = pass
    data['login'] = 'Log In'
    
  4. Send your login using a Requests Session:

    s = requests.Session()
    r = s.post(url, data=data)
    r.raise_for_status()
    
  5. Send all your future HTTP traffic through that Session.

  1. 对登录页面执行 GET ( https://m.facebook.com/)
  2. 使用 HTML 解析库(例如 BeautifulSoup)来解析 HTML 并找到表单字段的默认值。
    • 默认值都在<input>元素下方的 HTML 元素中#login_form。您需要按名称(例如charset_test)找到它们,然后提取它们的value属性。
    • 弄清楚如何做到这一点超出了这个答案的范围,所以我不打算深入研究。
  3. 将表单字段的默认值与您的电子邮件和密码结合起来,如下所示:

    data = {
        'lsd': lsd,
        'charset_test': csettest, 
        'version': version,
        'ajax': ajax,
        'width': width,
        'pxr': pxr,
        'gps': gps,
        'm_ts': mts,
        'li': li,
    }
    data['email'] = email
    data['pass'] = pass
    data['login'] = 'Log In'
    
  4. 使用 Requests 发送您的登录信息Session

    s = requests.Session()
    r = s.post(url, data=data)
    r.raise_for_status()
    
  5. 通过它发送所有未来的 HTTP 流量Session

As you can see, this is a non-trivial way of doing things. That's because it's not expected that programs will use the website to log in: instead, you're expected to use their SDKor their web APIinstead.

如您所见,这是一种非同寻常的做事方式。那是因为预计程序不会使用网站登录:相反,您应该使用他们的SDK或他们的Web API

回答by Torxed

First of all, you need ALLthe form data. You can't just send user+pass, the server won't allow it.
Secondly you will need to take care and use the cookies recieved from Facebook in order for this to work.

首先,您需要所有表单数据。您不能只发送用户+通行证,服务器不允许。
其次,您需要注意并使用从 Facebook 收到的 cookie 才能使其正常工作。

But all in all, yes you can use requestor any other library.
But i would reccomend using their APIinstead.

但总而言之,是的,您可以使用request或任何其他库。
但我会建议改用他们的 API

回答by deinonychusaur

I can say it's quite annoying to log in to Facebook without using their API. They also like to change everything so often it is quite the job to maintain the code.

我可以说在不使用他们的 API 的情况下登录 Facebook 是很烦人的。他们还喜欢经常更改所有内容,因此维护代码是一项艰巨的工作。

I did this a while ago, but I don't think my code is up to speed with current Facebook. However it should be a useful starting-point:

我不久前这样做了,但我认为我的代码跟不上当前 Facebook 的速度。但是,它应该是一个有用的起点:

https://gitorious.org/blogsmashonfb/blogsmashonfb/source/4f7ee94a56fdffe9392485df8999e340f97f4bbe:

https://gitorious.org/blogsmashonfb/blogsmashonfb/source/4f7ee94a56fdffe9392485df8999e340f97f4bbe

It has two parts, a webcrawler and a Facebook-handler (the latter is what you are interested in).

它有两个部分,一个网络爬虫和一个 Facebook 处理程序(后者是你感兴趣的)。

One major issue you have in your code is that you must first visit Facebook, because they send you a login form with hidden elements that you need to send back.

您在代码中遇到的一个主要问题是您必须首先访问 Facebook,因为他们会向您发送一个登录表单,其中包含您需要发回的隐藏元素。

回答by rzaaeeff

I was also searching for answer. Doing it with requestsis pain. So, i used mechanize.

我也在寻找答案。这样做requests是痛苦的。所以,我使用了机械化。

import mechanize
browser = mechanize.Browser()
browser.set_handle_robots(False)
cookies = mechanize.CookieJar()
browser.set_cookiejar(cookies)
browser.addheaders = [('User-agent', 'Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.7 (KHTML, like Gecko) Chrome/7.0.517.41 Safari/534.7')]
browser.set_handle_refresh(False)

url = 'http://www.facebook.com/login.php'
self.browser.open(url)
self.browser.select_form(nr = 0)       #This is login-password form -> nr = number = 0
self.browser.form['email'] = YourLogin
self.browser.form['pass'] = YourPassw
response = self.browser.submit()
print response.read()

It works. mechanize.browseris emulated browser, so you don't need to send all form values. It will send them as normal browser, you should provide only login and password.

Good luck!

有用。mechanize.browser是模拟浏览器,因此您不需要发送所有表单值。它会像普通浏览器一样发送它们,您应该只提供登录名和密码。

祝你好运!

回答by Jon McClung

A library like RoboBrowsermakes things like logging into Facebook very easy:

RoboBrowser这样的库使登录 Facebook 之类的事情变得非常容易:

import robobrowser

class Facebook(robobrowser.RoboBrowser):

    url = 'https://facebook.com'

    def __init__(self, email, password):
        self.email = email
        self.password = password
        super().__init__()
        self.login()

    def login(self):
        self.open(self.url)    
        login_form = self.get_form(id='login_form')
        login_form['email'] = self.email
        login_form['pass'] = self.password
        self.submit_form(login_form)

回答by aumiom

As said by others using requests is a pain. You can do it by using selenium. Install selenium by going to their website or simply isntall it using pip.

正如其他人所说,使用请求是一种痛苦。你可以通过使用硒来做到这一点。通过访问他们的网站或简单地使用 pip 安装 selenium。

pip install -U selenium

I have written the code below. I tried it myself and it works.

我写了下面的代码。我自己试过了,效果很好。

from selenium.webdriver.firefox.firefox_binary import FirefoxBinary

binary = FirefoxBinary(r'C:\Program Files (x86)\Mozilla Firefox\firefox.exe')
driver = webdriver.Firefox(firefox_binary=binary)
driver.get('https://www.facebook.com/')


username= "your_username"
password = "your_password"

UN = driver.find_element_by_id('email')

UN.send_keys(username)

PS = driver.find_element_by_id('pass')

PS.send_keys(password)

LI = driver.find_element_by_id('loginbutton')

LI.click()

回答by Pablo

This works (April 2017)

这有效(2017 年 4 月)

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import argparse
import datetime
import json
import logging
import re
import random
import requests
import shutil
from pyquery import PyQuery as pq


def main(username, password):

    logging.basicConfig(filename='imgur2fb.log', level=logging.DEBUG)

    session = requests.session()

    uid, dtsg = login(session, username, password)


def login(session, username, password):

    '''
    Login to Facebook
    '''

    # Navigate to the Facebook homepage
    response = session.get('https://facebook.com')

    # Construct the DOM
    dom = pq(response.text)

    # Get the lsd value from the HTML. This is required to make the login request
    lsd = dom('[name="lsd"]').val()

    # Perform the login request
    response = session.post('https://www.facebook.com/login.php?login_attempt=1', data={
        'lsd': lsd,
        'email': username,
        'pass': password,
        'default_persistent': '0',
        'timezone': '-60',
        'lgndim': '',
        'lgnrnd': '',
        'lgnjs': '',
        'locale':'en_GB',
        'qsstamp': ''
    })

    '''
    Get the users ID and fb_dtsg token. The fb_dtsg token is required when making requests as a logged in user. It
    never changes, so we only need to grab this token once.

    If the login was successful a cookie 'c_user' is set by Facebook. If the login failed, the 'c_user' cookie
    will not be present. This will raise an exception.
    '''
    try:
        uid = session.cookies['c_user']
        dtsg = re.search(r'(type="hidden" name="fb_dtsg" value="([0-9a-zA-Z-_:]+)")', response.text).group(1)

        dtsg = dtsg[dtsg.find("value")+6:]
        dtsg = dtsg[1:-1]

    except KeyError:
        raise Exception('Login Failed!')

    return uid, dtsg



try:
    main(username='*****', password='*****')
except Exception, e:
    logging.exception(e)
    print e

回答by Sam Arthur Gillam

Here's my working Code (May 2017 Python 3.6). To make it work for you, just hard code your own USERNAME, PASSWORD and PROTECTED_URL

这是我的工作代码(2017 年 5 月 Python 3.6)。为了让它为您服务,只需硬编码您自己的用户名、密码和 PROTECTED_URL

# https://gist.github.com/UndergroundLabs/fad38205068ffb904685
# this github example said tokens are also necessary, but I found 
# they were not needed
import requests

USERNAME = '[email protected]'
PASSWORD = '----password'
PROTECTED_URL = 'https://m.facebook.com/groups/318395378171876?view=members'
# my original intentions were to scrape data from the group page
# PROTECTED_URL = 'https://www.facebook.com/groups/318395378171876/members/'
# but the only working login code I found needs to use m.facebook URLs
# which can be found by logging into https://m.facebook.com/login/ and 
# going to the the protected page the same way you would on a desktop

def login(session, email, password):
    '''
    Attempt to login to Facebook. Returns cookies given to a user
    after they successfully log in.
    '''

    # Attempt to login to Facebook
    response = session.post('https://m.facebook.com/login.php', data={
        'email': email,
        'pass': password
    }, allow_redirects=False)

    assert response.status_code == 302
    assert 'c_user' in response.cookies
    return response.cookies

if __name__ == "__main__":

    session = requests.session()
    cookies = login(session, USERNAME, PASSWORD)
    response = session.get(PROTECTED_URL, cookies=cookies, 
allow_redirects=False)
    assert response.text.find('Home') != -1

    # to visually see if you got into the protected page, I recomend copying
    # the value of response.text, pasting it in the HTML input field of
    # http://codebeautify.org/htmlviewer/ and hitting the run button

回答by durga prasad paidi

First you need to know the data to be posted. Follow this link.

首先你需要知道要发布的数据。按照这个链接

After you get all the required data the code is simple as follows:

获得所有必需的数据后,代码很简单,如下所示:

import requests, bs4`    
s = requests.Session()
url = 'https://www.facebook.com/login'

res = s.get(url)
form_data = {
        # Copy paste the form data here as a valid python dict
}
s.post(url, data=form_data)

# Now try accessing your profile from sessions object

This worked for me.

这对我有用。