7

ubuntu サーバーで実行されているスクリプトから自分の yahoo アカウントにログインしたいと考えています。mechanize で python を使用しようとしましたが、私の計画には欠陥があります。

これは私が現時点で持っているコードです。

        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()

私が受け取る応答は、赤い太字のテキストが表示された Yahoo ログイン ページです。「ブラウザで Javascript を有効にする必要があります」など。mechanize docs には、JS で Cookie を作成するページについて言及しているセクションがありますが、残念ながら、ヘルプ ページは HTTP 400 を返します (運が良かっただけです)。

JavaScript の機能を理解し、それを手動で実行するのは、非常に難しい作業のように思えます。ubuntuサーバーで実行できる限り、任意のツール/言語に切り替えたいと思います. ログインに別のツールを使用してから、ログイン Cookie を Python スクリプトに戻すことを意味する場合でも。ヘルプ/アドバイスをいただければ幸いです。

アップデート:

  • Yahoo API を使用したくない

  • スクレイピーでも試してみましたが、同じ問題が発生すると思います

私のスクレイピースクリプト

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()

スクレイピースクリプトは「https://login.yahoo.com/config/login」を出力するだけで……ブー

4

6 に答える 6

3

これが機能することに驚いています:

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'] = 'testtest481@yahoo.com'
>>> 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
>>>

これを試してください:

"""                                                                        
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()                                                                     

必要に応じてエラー処理を追加します。

于 2012-08-17T23:17:09.123 に答える
2

ページが JavaScript を使用している場合は、リクエストや機械化の代わりに、ghost.pyなどを使用することを検討してください。ghost.py は WebKit クライアントをホストし、最小限の労力でこのようなトリッキーな状況を処理できるはずです。

于 2012-08-24T06:22:22.907 に答える
1

あなたのScrapyスクリプトは私のために働きます:

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)

出力:

stav@maia: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)}

環境:

stav@maia: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
于 2012-08-23T14:08:46.603 に答える
1

有効な js が必要で、表示が利用できない場合、python ではなく js であると考えられた phantomjs は優れたソリューションです:$

于 2012-08-23T21:36:26.540 に答える
0

使ってみませんFancyURLOpenerか?標準のHTTPエラーを処理し、prompt_user_passwd()機能を備えています。リンクから:

基本認証を実行するとき、FancyURLopenerインスタンスはそのprompt_user_passwd()メソッドを呼び出します。デフォルトの実装では、制御端末で必要な情報をユーザーに要求します。サブクラスは、必要に応じて、より適切な動作をサポートするためにこのメソッドをオーバーライドできます。

于 2012-08-29T17:06:22.597 に答える
0

Javascript API を備えたヘッドレス Web キットである PhantomJS を試すことができますhttp://phantomjs.org/プログラムによる Javascript 対応のブラウジングをサポートしています。

于 2012-08-29T16:21:09.793 に答える