Como ven, lo bonito del software libre es que con tan solo una búsqueda nos encontramos con programas maravillosos, los cuales podemos utilizar sin ninguna restricción (sí, ya se que esto no es completamente cierto). Ahora si, con ustedes el script:
- import libxml2dom
- import urllib2
- import urllib
- import pytesser
- import Image
- MAX_TRY = 5 # intentos antes de rendirse
- WAIT_TIME = 45 # tiempo de espera en segundos
- CAPTCHA_INPUT_NAME = "captcha"
- TEMP_FILE_NAME = "tempImg.gif"
- ID_DOWNLOAD_LINK = "downloadlink"
- def urlopen(url, data={}):
- """Abrir un recurso remoto, si se pasa data se envía por POST"""
- req = urllib2.Request(url, urllib.urlencode(data) if data else None)
- try:
- sock = urllib2.urlopen(req)
- try:
- data = sock.read()
- finally:
- sock.close()
- except IOError:
- print "el archivo no existe"
- else:
- return data
- def html2dom(page):
- """Retornar representación DOM de un documento html"""
- dom = libxml2dom.parseString(page, html=1)
- return dom
- def tag(elem, tag):
- """Encontrar descendientes de un elementos por su tag"""
- elements = elem.getElementsByTagName(tag)
- return elements[0] if len(elements) == 1 else elements
- def id(elem, Id):
- return elem.getElementById(Id)
- def attr(elem, attr):
- """Retornar atributo de un elemento"""
- return elem.getAttribute(attr)
- def save_img(uri):
- """Guardar imagen en local"""
- data = urlopen(uri)
- temp = file(TEMP_FILE_NAME, 'wb')
- temp.write(data)
- temp.close()
- def resolver_captcha():
- """Resolver captcha"""
- data = Image.open(TEMP_FILE_NAME)
- return pytesser.image_to_string(data)[:4]
- def fill_form(page):
- """Recolectar datos de formulario"""
- try:
- form = tag(page, 'form')
- img = tag(form, 'img')
- save_img(attr(img, "src"))
- # crear diccionario valores a enviar
- data = dict([(attr(i, 'name'),attr(i, 'value')) for i in tag(form, 'input')])
- # "rellenar" campo captcha
- captcha = resolver_captcha()
- data[CAPTCHA_INPUT_NAME] = captcha
- except:
- return None
- else:
- return (data, captcha)
- # Donde la magia sucede XD
- def get(url):
- """Descargar archivo"""
- times = 1
- # solo links de megaupload
- if url.find('http://www.megaupload.com/') != 0:
- print "%s no es un link de megaupload" % url
- return 0
- # Abrir pagina de formulario
- page = html2dom( urlopen(url) )
- while True:
- # llenamos el formulario
- data, captcha = fill_form(page)
- if not data or times == MAX_TRY:
- print "Error al abrir %s, puede que el link haya sido deshabilitado" % url
- return 0
- print "%s ==> intento %d\ncaptcha = %s" % (url, times, captcha)
- times += 1
- # Enviamos formulario por POST
- page = html2dom( urlopen(url, data) )
- # Si el captcha esta correcto obtenemos la página de descarga
- download_page = id(page, ID_DOWNLOAD_LINK)
- if download_page:
- download_link = tag( download_page , 'a' )
- import subprocess, time
- # please wait.... XD
- time.sleep(WAIT_TIME)
- args = ['wget', '-c', attr(download_link, 'href')]
- # empezamos a descargar ^_^
- proc = subprocess.Popen(args)
- retcode = proc.wait()
- return 1
- def get_from_file(file_path):
- """descargar múltiples archivos leyendo urls almacenadas en un archivo"""
- try:
- sock = file(file_path)
- try:
- lines = sock.readlines()
- finally:
- sock.close()
- except IOError:
- print "el archivo %s no existe" % file_path
- else:
- for line in lines:
- url = line.strip()
- if url:
- get( url )
- if __name__ == "__main__":
- import sys
- arg = sys.argv[1:]
- if arg[0] == "-f":
- get_from_file(arg[1])
- elif "http" in arg[0]:
- get(arg[0])
- else:
- print "uso:\nmget link_descarga\nmget -f /ruta/archivo/links_descarga\n"
Claro que le hacen falta algunas funcionalidades, pero para lo que lo necesito me basta y me sobra, ademas como ya dije existe una gran variedad de programas que hacen lo mismo. Si lo desean pueden descargar los archivos desde el siguiente enlace:
P.D.: Se aceptan criticas, solo no sean tan duros XD
2 Responses to “Saltándose los captchas de Megaupload con python”
Hola:
estoy tratando de implementar tu ejemplo, pero extrañamente python se queja que libxml2dom no tiene atributo parseString(), esto tiene algún sentido para ti?
He colocado el packete de la libreria en donde tengo el script.
Saludos!
hola Gabriel.
me parece raro, acabe de descargar la version 0.5 y me funciono.
tal vez sea mejor que lo instales, entras al directorio libxml2dom-5.0 desde un terminal y ejecutas:
python setup.py install
Deja una respuesta