tags:

views:

199

answers:

3

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("[email protected]", "asdfasdf")
f.login()
A: 

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

Andrey Fedoseev
I thought this initially, but the reason I doubt it is the pattern. It doesnt work a few times then fail all in a row. Its completely random when it works and when it doesn't.
tehryan
Protip: Facebook does actually block after x attempts. I've run into the same problem
Robus
A: 

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.

Caio Romão
A: 

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':'[email protected]','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.

Robus