2012-08-15 18 views
7

Me gustaría iniciar sesión en mi cuenta yahoo desde un script que se ejecuta en un servidor ubuntu. He tratado de usar Python con mecanize, pero hay un defecto en mi plan.cómo iniciar sesión en Yahoo programáticamente desde un servidor ubuntu

Este es el código que tengo en este momento.

 loginurl = "https://login.yahoo.com/config/login" 
     br = mechanize.Browser() 
     cj = cookielib.LWPCookieJar() 
     br.set_cookiejar(cj) 
     br.set_handle_equiv(True) 
     br.set_handle_gzip(True) 
     br.set_handle_redirect(True) 
     br.set_handle_referer(True) 
     br.set_handle_robots(False) 
     br.set_handle_refresh(mechanize._http.HTTPRefreshProcessor(), max_time=1) 
     br.addheaders = [('User-agent', 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.1) Gecko/2008071615 Fedora/3.0.1-1.fc9 Firefox/3.0.1')] 
     r = br.open(loginurl) 
     html = r.read() 
     br.select_form(nr=0) 
     br.form['login']='[mylogin]' 
     br.form['passwd']='[mypassword]' 
     br.submit() 

     print br.response().read() 

La respuesta que recibo es una página de inicio de sesión de Yahoo con texto rojo en negrita. "Javascript debe estar habilitado en su cuenta bancaria" o algo similar. Hay una sección en los documentos mecanize que menciona páginas que crean cookies con JS, pero la página de ayuda devuelve un HTTP 400 (simplemente mi suerte)

Averiguar qué hace el javascript y luego hacerlo manualmente suena como un muy tarea difícil. Estaría dispuesto a cambiar a cualquier herramienta/idioma, siempre y cuando se pueda ejecutar en un servidor ubuntu. Incluso si eso significa usar una herramienta diferente para el inicio de sesión y luego pasar la cookie de inicio de sesión a mi script de python. Cualquier ayuda/consejo apreciado.

Actualización:

  • no deseo utilizar las API de Yahoo

  • También he tratado con scrapy, pero creo que el mismo problema se produce

Mi scrapy script

class YahooSpider(BaseSpider): 
name = "yahoo" 
start_urls = [ 
    "https://login.yahoo.com/config/login?.intl=us&.lang=en-US&.partner=&.last=&.src=&.pd=_ver%3D0%26c%3D%26ivt%3D%26sg%3D&pkg=&stepid=&.done=http%3a//my.yahoo.com" 
] 

def parse(self, response): 
    x = HtmlXPathSelector(response) 
    print x.select("//input/@value").extract() 
    return [FormRequest.from_response(response, 
       formdata={'login': '[my username]', 'passwd': '[mypassword]'}, 
       callback=self.after_login)] 

def after_login(self, response): 
    # check login succeed before going on 
    if response.url == 'http://my.yahoo.com': 
     return Request("[where i want to go next]", 
        callback=self.next_page, errback=self.error, dont_filter=True) 
    else: 
     print response.url 
     self.log("Login failed.", level=log.CRITICAL) 

def next_page(sekf, response): 
    x = HtmlXPathSelector(response) 
    print x.select("//title/text()").extract() 

El guión scrapy simplemente da salida a "https://login.yahoo.com/config/login" ...... Boo

+0

¿No hay API de Yahoo para ese tipo de cosas? –

+0

Sí, pero lamentablemente su funcionalidad limitada – DrLazer

+0

No tengo ningún problema con el script. – xbb

Respuesta

3

me sorprende que esto funciona:

Python 2.6.6 (r266:84292, Dec 26 2010, 22:31:48) 
[GCC 4.4.5] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> from BeautifulSoup import BeautifulSoup as BS 
>>> import requests 
>>> r = requests.get('https://login.yahoo.com/') 
>>> soup = BS(r.text) 
>>> login_form = soup.find('form', attrs={'name':'login_form'}) 
>>> hiddens = login_form.findAll('input', attrs={'type':'hidden'}) 
>>> payload = {} 
>>> for h in hiddens: 
...  payload[str(h.get('name'))] = str(h.get('value')) 
... 
>>> payload['login'] = '[email protected]' 
>>> payload['passwd'] = '********' 
>>> post_url = str(login_form.get('action')) 
>>> r2 = requests.post(post_url, cookies=r.cookies, data=payload) 
>>> r3 = requests.get('http://my.yahoo.com', cookies=r2.cookies) 
>>> page = r3.text 
>>> pos = page.find('testtest481') 
>>> print page[ pos - 50 : pos + 300 ] 
    You are signed in as: <span class="yuhead-yid">testtest481</span>  </li> </ul></li><li id="yuhead-me-signout" class="yuhead-me"><a href=" 
http://login.yahoo.com/config/login?logout=1&.direct=2&.done=http://www.yahoo.com&amp;.src=my&amp;.intl=us&amp;.lang=en-US" target="_top" rel="nofoll 
ow">   Sign Out  </a><img width='0' h 
>>> 

Por favor, dar a este una prueba:

"""                   
ylogin.py - how-to-login-to-yahoo-programatically-from-an-ubuntu-server  

http://stackoverflow.com/questions/11974478/        
Test my.yahoo.com login using requests and BeautifulSoup.     
"""                   

from BeautifulSoup import BeautifulSoup as BS        
import requests                

CREDS = {'login': 'CHANGE ME',            
     'passwd': 'CHANGE ME'}            
URLS = {'login': 'https://login.yahoo.com/',        
     'post': 'https://login.yahoo.com/config/login?',     
     'home': 'http://my.yahoo.com/'}          

def test():                 
    cookies = get_logged_in_cookies()          
    req_with_logged_in_cookies = requests.get(URLS['home'], cookies=cookies)  
    assert 'You are signed in' in req_with_logged_in_cookies.text 
    print "If you can see this message you must be logged in." 

def get_logged_in_cookies():            
    req = requests.get(URLS['login'])          
    hidden_inputs = BS(req.text).find('form', attrs={'name':'login_form'})\ 
           .findAll('input', attrs={'type':'hidden'}) 
    data = dict(CREDS.items() + dict((h.get('name'), h.get('value')) \  
             for h in hidden_inputs).items()) 
    post_req = requests.post(URLS['post'], cookies=req.cookies, data=data) 
    return post_req.cookies             

test()                  

Agregue el manejo de errores según sea necesario.

+0

Me sorprende que también funcione. copié la carta de su guión por una carta, solo reemplazando su cuenta con la mía. el resultado para mí no es resultado ... porque "pos" es -1 y sigo apareciendo en la página Iniciar sesión única en la que puedo pensar es que mi versión de Python es 2.7.2+ y [GCC 4.6. 1] en linux2 – DrLazer

+0

He añadido una recompensa para condimentar un poco las cosas. – DrLazer

+0

Disculpa la demora. Se fue para el fin de semana de vacaciones bancarias. Ok He intentado su script modificado (gracias por publicarlo). – DrLazer

1

Su guión Scrapy funciona para mí:

from scrapy.spider import BaseSpider 
from scrapy.http import FormRequest 
from scrapy.selector import HtmlXPathSelector 

class YahooSpider(BaseSpider): 
    name = "yahoo" 
    start_urls = [ 
     "https://login.yahoo.com/config/login?.intl=us&.lang=en-US&.partner=&.last=&.src=&.pd=_ver%3D0%26c%3D%26ivt%3D%26sg%3D&pkg=&stepid=&.done=http%3a//my.yahoo.com" 
    ] 

    def parse(self, response): 
     x = HtmlXPathSelector(response) 
     print x.select("//input/@value").extract() 
     return [FormRequest.from_response(response, 
        formdata={'login': '<username>', 'passwd': '<password>'}, 
        callback=self.after_login)] 

    def after_login(self, response): 
     self.log('Login successful: %s' % response.url) 

Salida:

[email protected]:myproj$ scrapy crawl yahoo 
2012-08-22 20:55:31-0500 [scrapy] INFO: Scrapy 0.15.1 started (bot: drzyahoo) 
2012-08-22 20:55:31-0500 [scrapy] DEBUG: Enabled extensions: LogStats, TelnetConsole, CloseSpider, WebService, CoreStats, SpiderState 
2012-08-22 20:55:31-0500 [scrapy] DEBUG: Enabled downloader middlewares: HttpAuthMiddleware, DownloadTimeoutMiddleware, UserAgentMiddleware, RetryMiddleware, DefaultHeadersMiddleware, RedirectMiddleware, CookiesMiddleware, HttpCompressionMiddleware, ChunkedTransferMiddleware, DownloaderStats 
2012-08-22 20:55:31-0500 [scrapy] DEBUG: Enabled spider middlewares: HttpErrorMiddleware, OffsiteMiddleware, RefererMiddleware, UrlLengthMiddleware, DepthMiddleware 
2012-08-22 20:55:31-0500 [scrapy] DEBUG: Enabled item pipelines: 
2012-08-22 20:55:31-0500 [yahoo] INFO: Spider opened 
2012-08-22 20:55:31-0500 [yahoo] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min) 
2012-08-22 20:55:31-0500 [scrapy] DEBUG: Telnet console listening on 0.0.0.0:6023 
2012-08-22 20:55:31-0500 [scrapy] DEBUG: Web service listening on 0.0.0.0:6080 
2012-08-22 20:55:32-0500 [yahoo] DEBUG: Crawled (200) <GET https://login.yahoo.com/config/login?.intl=us&.lang=en-US&.partner=&.last=&.src=&.pd=_ver%3D0%26c%3D%26ivt%3D%26sg%3D&pkg=&stepid=&.done=http%3a//my.yahoo.com> (referer: None) 
[u'1', u'', u'', u'', u'', u'', u'', u'us', u'en-US', u'', u'', u'93s42g583b3cg', u'0', u'L0iOlEQ1EbZ24TfLRpA43s5offgQ', u'', u'', u'', u'', u'', u'0', u'Y', u'http://my.yahoo.com', u'_ver=0&c=&ivt=&sg=', u'0', u'0', u'0', u'5', u'5', u'', u'y'] 
2012-08-22 20:55:32-0500 [yahoo] DEBUG: Redirecting (meta refresh) to <GET http://my.yahoo.com> from <POST https://login.yahoo.com/config/login> 
2012-08-22 20:55:33-0500 [yahoo] DEBUG: Crawled (200) <GET http://my.yahoo.com> (referer: https://login.yahoo.com/config/login?.intl=us&.lang=en-US&.partner=&.last=&.src=&.pd=_ver%3D0%26c%3D%26ivt%3D%26sg%3D&pkg=&stepid=&.done=http%3a//my.yahoo.com) 
2012-08-22 20:55:33-0500 [yahoo] DEBUG: Login successful: http://my.yahoo.com 
2012-08-22 20:55:33-0500 [yahoo] INFO: Closing spider (finished) 
2012-08-22 20:55:33-0500 [yahoo] INFO: Dumping spider stats: 
    {'downloader/request_bytes': 2447, 
    'downloader/request_count': 3, 
    'downloader/request_method_count/GET': 2, 
    'downloader/request_method_count/POST': 1, 
    'downloader/response_bytes': 77766, 
    'downloader/response_count': 3, 
    'downloader/response_status_count/200': 3, 
    'finish_reason': 'finished', 
    'finish_time': datetime.datetime(2012, 8, 23, 1, 55, 33, 837619), 
    'request_depth_max': 1, 
    'scheduler/memory_enqueued': 3, 
    'start_time': datetime.datetime(2012, 8, 23, 1, 55, 31, 271262)} 

Medio Ambiente:

[email protected]:myproj$ scrapy version -v 
Scrapy : 0.15.1 
lxml : 2.3.2.0 
libxml2 : 2.7.8 
Twisted : 11.1.0 
Python : 2.7.3 (default, Aug 1 2012, 05:14:39) - [GCC 4.6.3] 
Platform: Linux-3.2.0-29-generic-x86_64-with-Ubuntu-12.04-precise 
1

Cuando está habilitado JS que se necesita, y no visualización está disponible, PhantomJS es una buena solución, pensó que era js, no python: $

2

Si la página usa javascript, puede considerar usar algo como ghost.py en lugar de solicitudes o mecanizar. ghost.py aloja un cliente WebKit y debería ser capaz de manejar situaciones complicadas como estas con un mínimo esfuerzo.

+0

Oh, eso está bien, no sabía que había un python equivalente a phantomjs :) – Tshirtman

0

Puede probar PhantomJS, un kit web sin cabeza con Javascript API http://phantomjs.org/ Admite la navegación programática habilitada para Javascript.

0

¿Por qué no utilizar FancyURLOpener? Maneja errores HTTP estándar y tiene la función prompt_user_passwd().Desde el enlace:

Al realizar la autenticación básica, una instancia FancyURLopener llama a su método prompt_user_passwd(). La implementación predeterminada solicita a los usuarios la información requerida en el terminal de control. Una subclase puede anular este método para admitir un comportamiento más apropiado si es necesario.

Cuestiones relacionadas