Logging into facebook with python

2020-02-04 06:39发布

If I run the following code 10 times in a row, it will work about half the time and fail the rest. Anyone know why?

import urllib2, cookielib, re, os, sys

class Facebook():
    def __init__(self, email, password):
        self.email = email
        self.password = password

        cj = cookielib.CookieJar()
        opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
        opener.addheaders = [('Referer', 'http://login.facebook.com/login.php'),
                            ('Content-Type', 'application/x-www-form-urlencoded'),
                            ('User-Agent', 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)')]
        self.opener = opener

    def login(self):
        url = 'https://login.facebook.com/login.php?login_attempt=1'
        data = "locale=en_US&non_com_login=&email="+self.email+"&pass="+self.password+"&lsd=20TOl"

        usock = self.opener.open('http://www.facebook.com')
        usock = self.opener.open(url, data)
        if "Logout" in usock.read():
            print "Logged in."
        else:
            print "failed login"
            print usock.read()
            sys.exit()

f = Facebook("test@gmail.com", "asdfasdf")
f.login()

标签: python
5条回答
\"骚年 ilove
2楼-- · 2020-02-04 06:48

Okay, I think I found the answer by basically looking at the response data.

"Logout" does not exist - at least for me -, yet, "Log out" and "logout" does (the later appears as logout.php, which probably won't change on different locales). So, for your particular issue, just replace "Log out" with "logout" and you're all set.

Now, as to why it was working after the first try, I didn't bother to check

Also, I'd suggest using urllib's urlencode for sending your data to avoid nasty bugs when sending stuff with "&", ";" and other characters used for control. (The "@" from the e-mails should be encoded also, but it doesn't seem to break this particular case)

Note: My test was basically changing the string and running it over a loop for some time, no issues were detected. If it does break for you, maybe Andrey is right.

查看更多
聊天终结者
3楼-- · 2020-02-04 07:05

So I tried your code, and got it to log in once, then like you I had trouble logging in again. On a line before the 'if' statement, I added print usock.read() and ended up getting a bunch of html code. I then dropped that code into a notepad, saved it as an html file, and pulled it up. This is what's happening: Facebook gets suspicious that we're logging in from a computer program, and is waiting for us to verify that we're real by showing a captcha word. The program doesn't account for this, and prints "Failed login" when it's really more of a pending login.

查看更多
叼着烟拽天下
4楼-- · 2020-02-04 07:11

I've run into the same problem. The only solution I found was... that facebook mobile is more stable.

class Acc:
    jar = cookielib.CookieJar()
    cookie = urllib2.HTTPCookieProcessor(jar)       
    opener = urllib2.build_opener(cookie)

    headers = {
        "User-Agent" : "Mozilla/5.0 (X11; U; FreeBSD i386; en-US; rv:1.8.1.14) Gecko/20080609 Firefox/2.0.0.14",
        "Accept" : "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,text/png,*/*;q=0.5",
        "Accept-Language" : "en-us,en;q=0.5",
        "Accept-Charset" : "ISO-8859-1",
        "Content-type": "application/x-www-form-urlencoded",
        "Host": "m.facebook.com"
    }

    def login(self):
        try:
            params = urllib.urlencode({'email':'test@test.test','pass':'dempassword','login':'Log+In'})
            req = urllib2.Request('http://m.facebook.com/login.php?m=m&refsrc=m.facebook.com%2F', params, self.headers)
            res = self.opener.open(req)
            html = res.read()

            #print res.getheader('location').split('/')[3]

        except urllib2.HTTPError, e:
            print e.msg
        except urllib2.URLError, e:
            print e.reason[1]
        return False

    def fetch(self,url):
        req = urllib2.Request(url,None,self.headers)
        res = self.opener.open(req)
        return res.read()

bla = Acc()
bla.login()

Also, facebook mobile isn't filled up with ajax, so figuring out what requests to make is much easier.

查看更多
倾城 Initia
5楼-- · 2020-02-04 07:11

Maybe Facebook limits the maximum number of login attempts per minute. It's just a guess.

查看更多
我命由我不由天
6楼-- · 2020-02-04 07:13

The fix worked for me, every time. Then I wanted to actually read the content of the page after logging in. For this, I added a 'print usock.read()' right after 'print 'Logged in'', but that returned an empty string. I guessed it's because usock is getting called twice, so I just modified the first call to usock:

    a = usock.read()
    if "logout" in a:
        print "Logged in."
        return a

This way there's only one call to usock, the first time, and it works. Instead of print a, I then used return a, because then I could directly use login() to return the page source. But please suit yourself.

查看更多
登录 后发表回答