2018年1月28日日曜日

Pythonスクレイピングによるfreemlの過去ログ取得方法

始めに

Pythonを使ってスクレイピングをしてfreemlの過去ログをダウンロードするスクリプトを組んだので紹介します。
ちなみに同じようなスクレイピング用のスクリプトをRubyでも組んだことがありますが
Pythonが圧倒的に使いやすいです。
Rubyでのスクレイピングでは以下の様な問題があります。
・解説サイトによって書き方のばらつきが多くコードが読みにくい
・エラーで通信が頻繁に終了する
・HTMLの解析関数にバグが多い(Pythonにバグがないとは言っていない)
※HTMLに関しては、バグ以前にスクレイピング先のサイトのHTMLが適切に書かれていない場合も多いため、どちらが原因とは言えない


プログラム

プログラムは以下の通りです。
__ここから__
import requests #http通信
from bs4 import BeautifulSoup #HTML解析
from urllib.parse import urljoin #URL解析
import re #正規表現
import time #スリープ


# メールアドレスとパスワードの指定(自分のfreemlのパスワード)
# 例↓
# USER = "test@test.com"
# PASS = "testpass"
USER = "id"
PASS = "password"

# ダウンロード開始番号
# 例:[MLの名前:0814]のメールからダウンロードを開始したい場合814を記入
startNum = 1

# ダウンロード数(ダウンロード開始番号から数えて何通分ダウンロードするか)
dlNum = 200

# ダウンロード先フォルダ
# このフォルダはあらかじめ作らないとエラーになる
dlFolder = "./Data/"


# セッションを開始
session = requests.session()

# ログイン
login_info = {
    "email":USER,
    "password":PASS,
    "back":"index.php",
    "mml_id":"0"
}

# action
url_login = "https://www.freeml.com/ep.umzx/grid/General/node/SpLoginProcess"
res = session.post(url_login, data=login_info)
res.raise_for_status() # エラーならここで例外を発生させる

# ページ遷移
res = session.get("https://www.freeml.com/ep.umzx/grid/User/node/HomeFront")
res.raise_for_status()

# ページ遷移、このページからスクレイピングスタート
# 「MLの名前」の部分は必要に応じて変えること
res = session.get("https://www.freeml.com/MLの名前/" + str(startNum))
res.raise_for_status()

#ループ、スクレイピングページ数指定
for i in range(0, dlNum):
title = BeautifulSoup(res.text, "html5lib").select(".mlc_text_14 > span")[0].string #タイトル取得
title = re.sub(r'[\\|/|:|?|.|"|<|>|\|*|\n|]', '-', str(title)) #ファイルネームに使えない文字列を除去

dateAndTime = BeautifulSoup(res.text, "html5lib").select(".table_bg > table > tbody > tr")[2].td.string
dateAndTime = re.sub(r'[\\|/|:|?|.|"|<|>|\|]', '-', str(dateAndTime)) #ファイルネームに使えない文字列を除去

mailNum = BeautifulSoup(res.text, "html5lib").select(".table_bg > table > tbody > tr")[3].td.string
mailNum = re.search('([0-9]+)', mailNum)[0]
contents = BeautifulSoup(res.text, "html5lib").select(".mlc_text_area1")[0].p #.stringを使うと上手く処理されないため正規表現を使用
contents = re.sub(r'<[^>]*?>', '', str(contents)) #正規表現によりタグを削除
print(str(dateAndTime) + "  " + str(title) + "  " + str(mailNum))
f = open(str(dlFolder) + str(dateAndTime) + "  " + str(title) + "  " + str(mailNum) + ".txt", "w") # 書き込みモードで開く

#環境依存文字に対応
contents = contents.replace('\ufffd', '1')

f.write(str(contents)) # 引数の文字列をファイルに書き込む
f.close() # ファイルを閉じる
nextUrl = BeautifulSoup(res.text, "html5lib").select(".mlc_link_area2 > .link_right")[1].a.attrs["href"]
# ページ遷移
res = session.get("https://www.freeml.com" + nextUrl)
res.raise_for_status()

# 10回ごとに2秒スリープ、サーバー負荷を軽減
if i % 10 == 0:
time.sleep(2)
__ここまで__


過去のMLを遡って解析する機会があったので組んでみました。
何かの活動でMLを使用している場合、それを遡ることで今までの流れや工夫に気づくことができると思います。
ぜひ活用してください。

0 件のコメント:

コメントを投稿