Python form POST using urllib2 (also question on saving/using cookies)
- by morpheous
I am trying to write a function to post form data and save returned cookie info in a file so that the next time the page is visited, the cookie information is sent to the server (i.e. normal browser behavior).
I wrote this relatively easily in C++ using curlib, but have spent almost an entire day trying to write this in Python, using urllib2 - and still no success.
This is what I have so far:
import urllib, urllib2
import logging
# the path and filename to save your cookies in
COOKIEFILE = 'cookies.lwp'
cj = None
ClientCookie = None
cookielib = None
logger = logging.getLogger(__name__)
# Let's see if cookielib is available
try:
    import cookielib
except ImportError:
    logger.debug('importing cookielib failed. Trying ClientCookie')
    try:
        import ClientCookie
    except ImportError:
        logger.debug('ClientCookie isn\'t available either')
        urlopen = urllib2.urlopen
        Request = urllib2.Request
    else:
        logger.debug('imported ClientCookie succesfully')
        urlopen = ClientCookie.urlopen
        Request = ClientCookie.Request
        cj = ClientCookie.LWPCookieJar()
else:
    logger.debug('Successfully imported cookielib')
    urlopen = urllib2.urlopen
    Request = urllib2.Request
    # This is a subclass of FileCookieJar
    # that has useful load and save methods
    cj = cookielib.LWPCookieJar()
login_params = {'name': 'anon', 'password': 'pass' }
def login(theurl, login_params):
  init_cookies();
  data = urllib.urlencode(login_params)
  txheaders =  {'User-agent' : 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'}
  try:
    # create a request object
    req = Request(theurl, data, txheaders)
    # and open it to return a handle on the url
    handle = urlopen(req)
  except IOError, e:
    log.debug('Failed to open "%s".' % theurl)
    if hasattr(e, 'code'):
      log.debug('Failed with error code - %s.' % e.code)
    elif hasattr(e, 'reason'):
      log.debug("The error object has the following 'reason' attribute :"+e.reason)
      sys.exit()
  else:
    if cj is None:
      log.debug('We don\'t have a cookie library available - sorry.')
    else:
      print 'These are the cookies we have received so far :'
      for index, cookie in enumerate(cj):
        print index, '  :  ', cookie
      # save the cookies again  
      cj.save(COOKIEFILE) 
      #return the data
      return handle.read()
# FIXME: I need to fix this so that it takes into account any cookie data we may have stored
  def get_page(*args, **query):
    if len(args) != 1:
        raise ValueError(
            "post_page() takes exactly 1 argument (%d given)" % len(args)
        )
    url = args[0]
    query = urllib.urlencode(list(query.iteritems()))
    if not url.endswith('/') and query:
        url += '/'
    if query:
        url += "?" + query
    resource = urllib.urlopen(url)
    logger.debug('GET url "%s" => "%s", code %d' % (url,
                                                    resource.url,
                                                    resource.code))
    return resource.read() 
When I attempt to log in, I pass the correct username and pwd,. yet the login fails, and no cookie data is saved. 
My two questions are:
can anyone see whats wrong with the login() function, and how may I fix it?
how may I modify the get_page() function to make use of any cookie info I have saved ?