Отправка Важных Сообщений Из Вконтакте На Электронную Почту

Добрый день Наверняка многие сталкивались с ситуацией, что важная информация (новости, анонсы и т.п.

) публикуется ВКонтакте.

Но во-первых, туда не всегда можно попасть (вообще, в рабочее время находиться ВКонтакте неприлично!), а во-вторых, информацию приходится получать методом опроса, то есть постоянно обновляя страницу группы или что-то в этом роде.

похожий.

Отсюда родилась замечательная идея — было бы удобно, чтобы важные уведомления приходили на электронную почту.

А можно смотреть на это в работе и судорожно нажимать F5; вам не нужно постоянно обновляться.

Как оказалось, с помощью Python вы легко справитесь с этой задачей.



Попытка №1: API ВК

Для начала я постарался быть честным и использовать API ВК.

В Интернете мне даже удалось найти пару библиотек, которые могли авторизоваться и выполнять функции из API. К сожалению, ни один из них мне не подошел, поэтому мне удалось за пару часов собрать собственный велосипед. Ладно, дело сделано, но тут я столкнулся с неприятным моментом, а именно с помощью текущей версии API невозможно получать сообщения со стены группы (или я не нашел как это сделать, что тоже вероятный).

Остается один вариант – разбирать страницы ВКонтакте самостоятельно.

С одной стороны, это не очень законно, с другой стороны, такой подход позволяет получить любую информацию, которую я могу увидеть прямо в браузере.



Попытка №2: парсить страницы напрямую!



Вход на сайт
Прежде всего я попробовал с httplib И URLlib получить страницу входа.

Все чудесно и чудесно.

Я только что обнаружил, что мне придется писать много некрасивого кода, а также работать с куками.

И как-то меня это очень расстроило.

Я начал искать замену.

И я нашел замечательную библиотеку механизировать , который замечательно сделал за меня всю неинтересную работу по созданию соединений, обработке сессий и кукисов и т.д. Итак, с помощью механизации получаем главную страницу ВКонтакте:

  
  
  
  
   

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-код, чтобы найти в нём нужные сообщения.

Для этого нам понадобится библиотека HTMLПарсер .

Давайте создадим собственный класс парсера, который мы унаследуем от 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()

Самый простой код для отправки сообщений.

Я использовал smtp-сервер Яндекса: smtp.yandex.ru:587. Список получателей можно прочитать из конфига или жестко запрограммировать один почтовый адрес, как это было в моем случае.



Что произошло в конце

На выходе имеем:
  1. важные сообщения отправляются нам на электронную почту, то есть нет необходимости заходить в ВКонтакте и обновлять страницу самостоятельно
  2. опыт парсинга страниц
  3. чувство удовлетворения и гордости за себя
Стоит сказать, что этот код является основой; на него можно обернуть много чего.

Например, для любителей GUI можно сделать форму для ввода логина и пароля.

Также можно парсить сообщения по имени автора (например, отправлять все сообщения от имени группы), обрабатывать теги внутри сообщений и т. д., т. п.

и т. п.

Опыт показывает, что не следует переоценивать частоту обновления страниц; все сообщения по-прежнему будут получены, а чрезмерная активность может привести к временному бану.

Вот и все.

Спасибо за внимание! УПД.

Перенесен из ВКонтакте на Python. Теги: #python #вконтакте #механизировать #python

Вместе с данным постом часто просматривают: