22
22

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Pythonでyahooにログインする

Posted at

はじめに

こんにちは、Webスクレイピングに関して、いつもお世話になってます。
Python3、Requests、Beautifulsoup4の組み合わせは、大変便利なのですが、Yahooログインの様に、Javascriptで動的に要素を書き換えていくサイトは、requestsでは対応できない様です。

Seleniumの仕組みや検証については、詳しい方にお願いするとして^^;、実際にログインして、(好みと既存のソースとの兼ね合いで)requestsへセッションを渡すところまで実装してみました。
部分的には他の記事が詳しいのですが、古かったりまとまってるものが見つからなかったので、ご参考になれば。。

環境の準備から

  • Windows10Pro 64bit
  • Python 3.6.1
  • PhantomJS v2.1 Download (Windows / Mac OS X / Linux 64-bit)
> pip install requests
> pip install beautifulsoup4
> pip install selenium

> pip list --format=columns
beautifulsoup4    4.6.0
requests          2.18.1
selenium          3.5.0
(…他省略)

サンプルコード

User-Agent等、HttpRequestヘッダに設定するブラウザはご自由に。
Python不慣れなのはご容赦ください。

# -*- coding: utf-8 -*-

import logging
import time

from bs4 import BeautifulSoup
import requests
from selenium import webdriver

import os.path
_dir = os.path.dirname(os.path.abspath(__file__))


def create_session():
    s = requests.Session()
    s.headers.update({
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
        "Accept-Language": "ja,en-US;q=0.7,en;q=0.3",
        "User-Agent":
            "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:55.0) Gecko/20100101 Firefox/55.0"
    })
    return s


def yahoojp_session(target_url, login_id, password):

    headers = {
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
        "Accept-Language": "ja,en-US;q=0.7,en;q=0.3",
        "Connection": "keep-alive",
        "User-Agent":
            "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:55.0) Gecko/20100101 Firefox/55.0"
    }

    cap = webdriver.DesiredCapabilities.PHANTOMJS
    for key, val in headers.items():
        cap["phantomjs.page.customHeaders." + key] = val
    cap["phantomjs.page.settings.userAgent"] = headers["User-Agent"]

    try:
        # <class 'selenium.webdriver.phantomjs.webdriver.WebDriver'>
        driver = webdriver.PhantomJS()
    except Exception as e:
        logging.error(e)
        return None

    # クッキーを先に取得する
    driver.get(target_url)
    bs4 = BeautifulSoup(driver.page_source, "html5lib")
    login_url = bs4.find("a", attrs={"id": "msthdLogin"})["href"]

    driver.get(login_url)
    time.sleep(1)

    driver.find_element_by_name("login").send_keys(login_id)
    driver.find_element_by_name("btnNext").click()  # 次へボタン
    time.sleep(1)

    driver.find_element_by_name("passwd").send_keys(password)
    driver.find_element_by_name("btnSubmit").click()  # ログインボタン
    time.sleep(1)
    # driver.save_screenshot(_dir + "/login.png")   # ログイン済みを画像で確認できます

    # セッション情報をrequestsに移す
    s = create_session()
    for c in driver.get_cookies():
        s.cookies[c["name"]] = c["value"]

    driver.close()
    return s


if __name__ == '__main__':

    s = yahoojp_session("対象のURL", "ヤフーID", "ヤフーパスワード")

こちらの部分で、Selenium + PhantomJSのヘッドレスブラウザにて、クッキーの取得と実際にヤフーへアクセスしてログイン画面へのURLを取得しています。Parserは僕はbs4しか知らないです。(User-Agentによっては、要素ごと無くなるのでご注意)

    driver = webdriver.PhantomJS()

    # クッキーを先に取得する
    driver.get(target_url)
    bs4 = BeautifulSoup(driver.page_source, "html5lib")
    login_url = bs4.find("a", attrs={"id": "msthdLogin"})["href"]

PhantomJS?では、実際にブラウザにする動作をコーディングします。
その都度、画像でブラウザの状態を確認できて便利ですし、
非常に仕様変更に強いと思います。

    driver.get(login_url)
    time.sleep(1)

    driver.find_element_by_name("login").send_keys(login_id)
    driver.find_element_by_name("btnNext").click()  # 次へボタン
    time.sleep(1)

    driver.find_element_by_name("passwd").send_keys(password)
    driver.find_element_by_name("btnSubmit").click()  # ログインボタン
    time.sleep(1)
    # driver.save_screenshot(_dir + "/login.png")   # ログイン済みを画像で確認できます

このまま、webdriver(Selenium)+ Parserでスクレイピングして問題ないと思いますが、自分はrequests + BeautifulSoupの方が便利なので、セッション情報を渡してます。

    # セッション情報をrequestsに移す
    s = create_session()
    for c in driver.get_cookies():
        s.cookies[c["name"]] = c["value"]

    driver.close()
    return s

まとめ

ヘッドレスブラウザについて、勉強不足です…。
(Requestsの設定で解決できないか悩んだり、JS追ってみたり、mechanizeやSeleniumとSelenium-Requestsの違いで混乱したり、あとPhantomJSでなくても良いと思います)
ですが、ログイン等出来れば他はそれほど問題にならないので、非常に使えると思います。

参考資料

PythonでさくっとWebスクレイピングする (JavaScript読み込みにも対応しつつ)
Seleniumアレルギーのための処方箋
Requests: 人間のためのHTTP > API Document

22
22
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
22

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?