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()
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.
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.
I've run into the same problem. The only solution I found was... that facebook mobile is more stable.
Also, facebook mobile isn't filled up with ajax, so figuring out what requests to make is much easier.
Maybe Facebook limits the maximum number of login attempts per minute. It's just a guess.
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:
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.