Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python urllib2 login to minecraft.net

I got a problem. I am writing a simple script to login to minecraft.net, and then list all classic servers. But when I run my script, it just redirects me back to minecraft.net/login. Here is what I have so far:

import urllib2
import urllib
import re

url = "https://www.minecraft.net/login"
page = urllib2.urlopen(url)
data = page.read()
page.close()

authToken = re.search('name="authenticityToken"[\s]+value="(.+)"', data).group(1)

data_dict = {
    "username": "USERNAME",
    "password": "PASSWORD",
    "remember": "true",
    #"redirect": "https://www.minecraft.net",
    "authenticityToken": authToken
}
print urllib.urlencode(data_dict)
req = urllib2.Request(url, data=urllib.urlencode(data_dict))
page = urllib2.urlopen(req)
data = page.read()
page.close()

What I am doing wrong?

like image 321
JadedTuna Avatar asked Dec 26 '22 16:12

JadedTuna


2 Answers

What about using Selenium instead of urllib? When doing complex stuff like authentication etc. I prefer to use Selenium as it is like web browsing. This solution requires an installation of a Firefox.

Installation

>>> sudo pip install selenium

Code

from selenium import webdriver

# initialize the browser and go to the site.
browser = webdriver.Firefox()
url = 'https://www.minecraft.net/login'
user_name = 'your_user_name'
password = 'your_password'
browser.get(url)

# retrieve all necessary page elements
user_name_field = browser.find_element_by_id('username')
password_field = browser.find_element_by_id('password')    
user_name_field.send_keys(user_name)
password_field.send_keys(password)
sign_in_btn = browser.find_element_by_id('signin')

# log in
sign_in_btn.click()

I don't own a Minecraft account so I cannot test it, but you probably can retrieve all Minecraft servers thanks to methods like:

  • browser.find_elements_by_partial_link_text
  • browser.find_elements_by_class_name
  • browser.find_elements_by_css_selector

Generally, I recommend to test your Selenium code with ipython, where you can see the browser work. (Installation: sudo pip install ipython)

In the case of a lot of Javascript processing - please add the following lines to your code:

browser = webdriver.Firefox()
browser.browser.implicitly_wait(30) # seconds

If you plan to additionally support another browser you can support it with try catch clauses

import sys

browser = None
try:
    browser = webdriver.Firefox()
except Exception as e:
    try:
        browser = webdriver.Chrome()
    except Exception as e2:
        try:
            browser = webdriver.Safari()
        except Exception as e3:
            print 'Could not find Firefox, Chrome or Safari!' 
            sys.exit(0)

This nested try-except clause is not the best programming style, but I am sure it helps you to use it for your purposes. Taking the tab completion in IPython Selenium supports

  • Safari
  • Firefox
  • Opera and
  • IE.

In my case, I used Selenium mostly with Firefox.

like image 111
Jon Avatar answered Dec 28 '22 05:12

Jon


For any kind of semi-complicated HTTP requests, you should use the Requests module (http://requests.readthedocs.org/en/latest/) instead of urllib. It'll save you a lot of pain.

You'll need to do something like:

import requests
import re

data = requests.get("https://minecraft.net/login")
auth_token = re.search('name="authenticityToken"[\s]+value="(.+)"', data).group(1)

# If needed, you may have to urlencode all that.
data_dict = {
    "username": "USERNAME",
    "password": "PASSWORD",
    "remember": "true",
    #"redirect": "https://www.minecraft.net",
    "authenticityToken": auth_token
}

logged_in_data = requests.post("https://minecraft.net/login", data_dict)
like image 21
Max Noel Avatar answered Dec 28 '22 05:12

Max Noel