PythonでWebの特定部分を抜き出してメールで送る

某氏から相談をされたのでメモ。次のことがしたいとのこと。
http://www.rfi.fr/lffr/articles/001/script_journal_francais_facile.asp
というサイトのスクリプトを抜き出して朝7時に自分の携帯に送りたい。

これには次の3つの機能が必要である。
1.特定Webにアクセスしてスクリプトを抜き出す
2.Eメールに添付して送信する
3.上記を周期的に行う

これはどのプログラミング言語でもできるし、個人的にはRubyRails)を使うところだが
某氏はRuby使わないと思うのでPythonでやる。

1.特定Webにアクセスしてスクリプトを抜き出す(スクレイピング

まず抜き出したい部分のHTMLの構造(DOM:ドム→Document Object Model
を把握することが必要。
Safariで開発者オプションをONにした状態で、抜き出したい部分の上で右クリック>Inspect Elementsを
選択すると、Web Inspectorが開いて、選択した部分が示される。

基本的にはid="central-article-script-francais-facile"ってとこのスクリプトを抜き出したいってことがわかる。
PythonにはBeautifulSoupってライブラリがあるからそれを使う。
インストールしてなかったらここからダウンロード。
http://www.crummy.com/software/BeautifulSoup/bs4/download/

getscript.py

#! /usr/bin/env python                                                                
# -*- coding:utf-8 -*-                                                                

from bs4 import BeautifulSoup
import urllib2

url = "http://www.rfi.fr/lffr/articles/001/script_journal_francais_facile.asp"
html = urllib2.urlopen(url).read()
soup = BeautifulSoup(html)
content = soup.find("div",{"id":"central-article-script-francais-facile"}).contents

print content

これを実行すると

$ python getscript.py
[<p class="entete">Journal en fran&#231;ais facile</p>, <div class="bloc-photo"><h1>Edition du 11/09/2013 20:00</h1><div class="chapeau"><p><font color="#0000ff">Merci d'&#233;couter RFI. A Paris, il est 22 heures </font></p>
<p><font color="#0000ff">Fran&#231;ois Bernard </font></p>
<p><font color="#0000ff">C'est le journal en fran&#231;ais facile en compagnie de Z&#233;phyrin Kouadio , Bonsoir&#160; Z&#233;phyrin </font></p>
・・・中略・・・
</div>, u'\xa0\r\n\t\t', <div id="corps"></div>, <div class="signature"><p class="date">
				
					Article publi&#233; le
				
				11/09/2013</p></div>, u'\n', <div class="action">
<p><a href="javascript:rfifrImprimer();">Imprimer</a></p>
<p><a href="javascript:francaisRfifrEnvoyer('lffr');">Envoyer l'article</a></p>
</div>, <p class="clear">&#160;</p>]

って感じでとれるけど、HTMLタグが邪魔。
BeautifulSoupの機能でも除去できるらしいんだけど、こういうのは一般的には正規表現で除去する。
Pythonにはreモジュール(Regular Expression)っていうのがある。

#! /usr/bin/env python                                                                
# -*- coding:utf-8 -*-                                                                

from bs4 import BeautifulSoup
import urllib2
import re

url = "http://www.rfi.fr/lffr/articles/001/script_journal_francais_facile.asp"
html = urllib2.urlopen(url).read()
soup = BeautifulSoup(html)
texts = "\n".join( str(e.encode("utf-8")) for e in soup.find("div",{"id":"central-art\
icle-script-francais-facile"}).contents)
texts = re.sub('<[^>]*>', '', texts)
print texts

もういちど実行する。

$ python getscript.py

Journal en fran&#231;ais facile
Edition du 11/09/2013 20:00Merci d'&#233;couter RFI. A Paris, il est 22 heures 
Fran&#231;ois Bernard 
C'est le journal en fran&#231;ais facile en compagnie de Z&#233;phyrin Kouadio , Bonsoir&#160; Z&#233;phyrin 
Z&#233;phyrin Kouadio
Bonsoir 
FB /
Dans l'actualit&#233; de ce mercredi 11 septembre 
le secr&#233;taire d'Etat am&#233;ricain John Kerry et son homologue russe Sergue&#239; Lavrov qui ont pr&#233;vu de se rencontrer jeudi &#224; Gen&#232;ve.
ZK /
&#160;Les Etats-Unis ont comm&#233;mor&#233;&#160; le douzi&#232;me anniversaire des attentats du
・・・中略・・・
ZK /
Et apr&#232;s trois semaines de tergiversation chaque partie crie victoire… Pour la France et les Etats-Unis la fermet&#233; &#224; l’&#233;gard du r&#233;gime de Bachar Al Assad a pay&#233;. 


Imprimer
Envoyer l'article

Voila, ca marche!

2.Eメールに添付して送信する

PythonでEメールを送るには、Gメールのライブラリを使うのが簡単。
https://github.com/thedjpetersen/gmaillib
ダウンロードしたら

$ sudo python setup.py install

でインストールする。

スクリプトは簡単。
sendmail.py

import gmaillib
username = 'YOUR_GMAIL@gmail.com'
password = 'xxxxxxxx'
target = 'TARGET@address.com'
subject = "Today's script"
message = 'script comes here'

account = gmaillib.account(username, password)
account.send(target, subject, message)

1と2を組み合わせるとこうなる。

getscript.py(完成版)

#! /usr/bin/env python                                                                
# -*- coding:utf-8 -*-                                                                

from bs4 import BeautifulSoup
import urllib2
import re
import gmaillib

url = "http://www.rfi.fr/lffr/articles/001/script_journal_francais_facile.asp"
html = urllib2.urlopen(url).read()
soup = BeautifulSoup(html)
texts = "\n".join( str(e.encode("utf-8")) for e in soup.find("div",{"id":"central-art\
icle-script-francais-facile"}).contents)
texts = re.sub('<[^>]*>', '', texts)

username = 'YOUR_GMAIL@gmail.com'
password = 'xxxxxxxx'
target = 'TARGET@address.com'
subject = "Today's script"
message = texts

account = gmaillib.account(username, password)
account.send(target, subject, message)

これでPythonスクリプトは完成。

3.上記を周期的に行う

以上を周期化するために、Linuxのcrontabを使う。
使い方:http://d.hatena.ne.jp/satake7/20080615/p1

$ crontab -e

でエディタが起動する。

0 7 * * * python /PATH_TO_SCRIPT/getscript.py

って書いとけば毎朝7時にメールで送られる。

(追記)getscript.pyをコマンドとして認識させたかったら

$ sudo chmod a+x getscript.py
$ sudo mv getscript.py /usr/local/bin/

で実行権限与えてパス通しとく。

任意のLinuxサーバ上でcronを設定すればいい。ずっとネットにつないでるならMacでもいい。

たぶんRubyだったらもっと簡単に出来た気がする(今回もPythonエンコードで詰まった)。
RubyにはMechanizeっていうスクレイパーがある。

Enjoy!