Login to Facebook using python requests

Question:

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!

Asked By: alexryabkov

||

Answers:

First of all, you need ALL the 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.

But all in all, yes you can use request or any other library.
But i would reccomend using their API instead.

Answered By: Torxed

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.

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:

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).

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.

Answered By: deinonychusaur

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.

Answered By: Lukasa

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!

Answered By: rzaaeeff

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)
Answered By: Jon McClung

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 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 Firefoxfirefox.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()
Answered By: aumiom

This works (April 2017)

#!/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
Answered By: Pablo

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

# 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
Answered By: Sam Arthur Gillam

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.

Answered By: durga prasad paidi