Python3でメール本文内のURLを取得する方法

前回はメールの本文などを取得するところを解説しました。

 

まだ見ていない人はこちらを↓

Pythonでgmailの内容を取得する方法 本文、タイトルを取得する

基本としてこのコードの意味を理解してからのほうがやりやすいはずです。

 


import imaplib
import email	#この二つをimport

mail=imaplib.IMAP4_SSL('imap.gmail.com',993) 	#SMTPは993,POPは995
mail.login('メールアドレス','パスワード')
mail.select('inbox')	#メールボックスの選択

type,data=mail.search(None,'ALL')	#メールボックス内にあるすべてのデータを取得

for i in data[0].split():	#data分繰り返す
 ok,x=mail.fetch(i,'RFC822')	#メールの情報を取得
 ms=email.message_from_string(x[0][1].decode('iso-2022-jp'))	#パースして取得
 
 #本文を取得
 maintext=ms.get_payload()


mail.close()
mail.logout()

本文中のURLを取得

本文の内容はこのソースコードでは「maintext」に格納されています。

printで出力してみましょう。

 

流れとしては

  • 本文を行ごとに配列に格納
  • 「http://」と書かれている行を取得
  • 文中にある可能性があるので「http://」より前を削除
  • 同じように後を削除

という感じです。

 

本文を行ごとに配列に格納


lists=maintext.split("\n")

split()を使うとその文字列を()の中の文字で区切りリスト化します。

 

これでlistsに改行ごとに格納されました。

 

「http://」と書かれている行を取得


len=[]
for list in lists:
 if list.find('http://') >-1 or list.find('https://') > -1:
  len.append(list)

まずはlistに含まれている配列分繰り返します。

 

listには配列の要素がそのつど入ります。

 

list.find(‘http://’)というのは「listの中にhttp://という文字列が入っていたら、その文字が現れる場所を返し、入っていなければ-1を返す」ということです。

 

https://についても同様です。

 

それらのどちらかが入っている場合のみ、lenに格納されます。

 

文中にある可能性があるので「http://」より前を削除


httpurl=[]
for list in len:
 top=list.find('http')
 list=list[top:]
 httpurl.append(list)

ここで大切なのはlist[top:]というものです。

 

例を出してみます。

「文字列strのx番目の文字からy番目の文字を取得する」というときは


str=str[x:y]

と指定します。

 

x,yの指定がない場合は、最後まで取得します。

 

topには.find()を使ってhttpが出てくる番目の数を取得します。

 

同じように後を削除

これが一番面倒ですが、「改行や空白など」「ひらがな」「カタカナ」を探して、その要素の先頭を取得ます。

import reを追加する必要があります。

 

その要素から後ろを削除します。

 


httpurl=[]
for list in len:
 top=list.find('http')
 list=list[top:]
 a=re.search('[\sあ-んア-ン]',list)
 start=a.start()
 list=list[:start]
 httpurl.append(list)

さっきのソースコードに追加しましょう。

 

追加されたのは

 


a=re.search('[\sあ-んア-ン]',list)
start=a.start()
list=list[:start]

です。

 

\sは改行などの要素です。

 

これを探してsearch要素を格納。

 

格納した要素から「.start()」で、先頭文字番号を取得。

 

先ほどと同じ要領でlistの文字を削除。

 

今回は、[:start]で後ろの要素を削除します。

 

ここはまだ完全ではないので、改善する必要があります。

 

まとめ

これをすべてまとめるとこうなります。


import imaplib
import email	
import re

mail=imaplib.IMAP4_SSL('imap.gmail.com',993) 	#SMTPは993,POPは995
mail.login('メールアドレス','パスワード')
mail.select('inbox')	#メールボックスの選択

type,data=mail.search(None,'ALL')	#メールボックス内にあるすべてのデータを取得

for i in data[0].split():	#data分繰り返す
 ok,x=mail.fetch(i,'RFC822')	#メールの情報を取得
 ms=email.message_from_string(x[0][1].decode('iso-2022-jp'))	#パースして取得
 
 #本文を取得
 maintext=ms.get_payload()
 
 #URLを取得
 len=[]
 lists=maintext.split("\n")
 
 for list in lists:
  if list.find('http://') >-1 or list.find('https://') > -1:
   len.append(list)

 httpurl=[]
 for list in len:
  top=list.find('http')
  list=list[top:]
  a=re.search('[\sあ-んア-ン]',list)
  start=a.start()
  list=list[:start]
  httpurl.append(list)

 print(httpurl)
mail.close()
mail.logout()

これでurlが格納されたリストが取得されました。

 

文字列を削除するところでは、最初の文字は「http://」から始まるためわかりやすいのですが、後ろの要素がわかりません。

 

もっと効率のいいやり方があると思うのですが…。