VKontakteからの重要なメッセージをメールで送信

こんにちは

確かに多くの人が重要な情報(ニュース、発表など)がVKontakteで公開されている状況に遭遇しました。 しかし、まず、そこに着くことが常に可能であるとは限りません(通常、勤務時間中にVKontakteに座るのは下品です!)、そして次に、ポーリング、つまりグループのページなどを絶えず更新することによって情報を取得する必要があります。

ここから素晴らしい考えが生まれました-重要な通知がメールで届くと便利です。 そして職場では、 F5を絶えず更新する必要がなく、 必死に押すことができます。 判明したように、pythonを使用すると、このようなタスクに簡単に対処できます。



試行番号1:VK API



まず第一に、私は正直になり、VK APIを使用しようとしました。 ネットワーク上で、ログインしてAPIから機能を実行できるライブラリをいくつか見つけることができました。 残念ながら、それらのどれも私に適していないので、私は数時間で自転車を構築することができました。 さて、完了しましたが、ここで不快な瞬間に遭遇しました。つまり、現在のバージョンのAPIを使用してグループウォールからメッセージを受信する方法がありません(または、これを行う方法が見つかりませんでした)。 VKontakteページを自分で解析するためのオプションが1つしかありませんでした。 一方では、これはあまり合法ではありません。他方では、このアプローチにより、ブラウザで直接見ることができる情報を取得することが可能になります。



試行番号2:ページを直接解析する!



サイトにログイン


まず最初に、 httpliburllibを使用してログインページを取得しようとしました 。 すべてが素晴らしいです。 たくさんのいコードを書かなければならないし、クッキーでさえ働かなければならなかったことがわかりました...そして、どういうわけかそれは非常に悲しくなりました。 私は代替品を探し始めました。 そして、彼は、接続の作成、セッションの処理、Cookieの処理など、面白くない仕事をしてくれた素晴らしい機械化ライブラリを見つけました...

したがって、mechanizeを使用して、メインのVKページを取得します。

def initVK(): # Browser br = mechanize.Browser() # Cookie Jar cj = cookielib.LWPCookieJar() br.set_cookiejar(cj) # Browser options 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) # Follows refresh 0 but not hangs on refresh > 0 br.set_handle_refresh(mechanize._http.HTTPRefreshProcessor(), max_time=1) # Little cheating... 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')] br.open('http://vkontakte.ru') br.select_form(nr=0) br.form['email'] = EMAIL br.form['pass'] = PASSWORD br.submit() return br
      
      





説明として、vkontakte.ruでは最初のフォームは単なるログインフォームであると言います。 機械化の助けを借りて、それを記入して出来上がり、サイトにログインしました!

壁から重要なメッセージを受け取る


次のコードにより、グループページを取得できます。

 def getGroupHTML(br): br.open('http://vkontakte.ru/OUR_GROUP') html = br.response().read() return html
      
      





次に、受信したhtml-codeを直接解析して、必要なメッセージを見つけます。

このためには、 HTMLParserライブラリが必要です。 HTMLParserから継承する独自のパーサークラスを作成しましょう。

簡単にするために、何らかのパターンで始まるメッセージを探します(私のスクリプトでは「@ year2007」を使用しました)。

 class MyHTMLParser(HTMLParser): def __init__(self): HTMLParser.__init__(self) self.recording = False self.export_tag = False self.message = unicode('') def handle_starttag(self, tag, attrs): if tag == 'div': for name, value in attrs: if name == 'class' and value == 'wall_text': self.export_tag = True if name == 'class' and value == 'wall_post_text': self.recording = True def handle_endtag(self, tag): if tag == 'div': if self.recording: self.recording = False year = re.compile(PATTERN) if year.match(self.message): message_queue.append(year.sub('', self.message).strip()) self.message = unicode('') if self.export_tag: self.export_tag = False def handle_data(self, data): if self.recording: self.message += unicode(data, 'CP1251')
      
      





すべてのテキストはCP1251エンコーディングで提供され、ユニコードに変換されます。 wall_textクラスを持つレイヤーはメッセージを処理し、wall_post_textはメッセージのテキストを処理します。



これで、メッセージを受信するためのコードを無限ループにラップできます。 パスごとにメッセージをメールに送信しないようにするには、メッセージをキューに入れるか、時間を解析します。 簡単にするために、ターンを行います。

また、テキストに他のタグ(リンクなど)が含まれている可能性があることにも注意してください。 不幸なaway.phpを事前にカットして処理することもできます。 しかし、これらは詳細です。

 import codecs message_queue = [] try: f = codecs.open('/tmp/vk-last-message', 'r', encoding='utf-8') last_message = f.read() f.close() if len(last_message.strip()) == 0 : last_message = PATTERN except: last_message = PATTERN import time browser = initVK() import mymail while True: #print "Getting vk.com pages" html = getGroupHTML(browser) p = MyHTMLParser() p.feed(html) #print message_queue msgSent = 0 for msg in message_queue: if msg == last_message : break #messageForSend = processMsg(msg) print msg mymail.sendMessage(msg) msgSent += 1 if len(message_queue) > 0 and msgSent > 0 and len(last_message.strip()) > 0: last_message = message_queue[0] f = codecs.open('/tmp/vk-last-message', 'w', encoding='utf-8') f.write(last_message) f.close() #print "last message: " + last_message message_queue = [] #print "Sleeping..." time.sleep(60)
      
      





メールでメッセージを送信する


ここで、mymailモジュールの秘密を明らかにします。

 import smtplib from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText def sendMessage(text): if len(text) == 0: print "Empty message" return fromaddr = FROM_ADDR toaddrs = LIST_OF_RECEPIENTS #text = 'test message' msg = MIMEMultipart('alternative') msg['Subject'] = "year2007@vkontakte" msg['From'] = fromaddr msg['To'] = toaddrs mime_text = MIMEText(text, 'plain', 'utf-8') msg.attach(mime_text) # Credentials (if needed) username = USER password = PASSWD # The actual mail send server = smtplib.SMTP('SMTP_SERVER:SMTP_PORT') server.starttls() server.login(username,password) server.sendmail(fromaddr, toaddrs, msg.as_string()) server.quit()
      
      





メッセージを送信するための最も簡単なコード。 Yandex smtpサーバーを使用しました:smtp.yandex.ru ∗ 87。 受信者のリストは、私の場合のように、構成から読み取るか、1つの住所をハードコードすることができます。



結果として何が起こったのか



出力には次のものがあります。

  1. 重要なメッセージがメールに届きます。つまり、VKontakteに行って自分でページを更新する必要はありません。
  2. ページ解析体験
  3. 自己満足と誇り


このコードが基礎であり、多くのことをそれにねじ込むことができると言う価値があります。 たとえば、GUIのファンの場合は、ログインとパスワードを入力するフォームを作成できます。 また、作成者の名前でメッセージを解析したり(たとえば、グループに代わってすべてのメッセージを送信したり)、メッセージ内のタグを処理したりすることもできます。

経験によれば、ページのリフレッシュレートを過大評価すべきではありません。それでも、すべてのメッセージが受信され、過度のアクティビティに対しては一時的な禁止で罰せられる可能性があります。



それだけです。 ご清聴ありがとうございました!



UPD。 VKontakteからPythonに移動しました。



All Articles