Login to Facebook using python requests

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

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?

Thanks!


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 tools to monitor your web requests.

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:

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:

  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_form element. You'll want to find them by name (e.g. charset_test) and then pull out their value attribute.
    • 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.

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 SDK or their web API instead.


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

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'
browser.open(url)
browser.select_form(nr = 0)       #This is login-password form -> nr = number = 0
browser.form['email'] = YourLogin
browser.form['pass'] = YourPassw
response = browser.submit()
print response.read()

It works. mechanize.browser is 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!


A library like RoboBrowser makes things like logging into Facebook very easy:

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)