Добрый день Наверняка многие сталкивались с ситуацией, что важная информация (новости, анонсы и т.п.
) публикуется ВКонтакте.
Но во-первых, туда не всегда можно попасть (вообще, в рабочее время находиться ВКонтакте неприлично!), а во-вторых, информацию приходится получать методом опроса, то есть постоянно обновляя страницу группы или что-то в этом роде.
похожий.
Отсюда родилась замечательная идея — было бы удобно, чтобы важные уведомления приходили на электронную почту.
А можно смотреть на это в работе и судорожно нажимать F5; вам не нужно постоянно обновляться.
Как оказалось, с помощью Python вы легко справитесь с этой задачей.
Попытка №1: API ВК
Для начала я постарался быть честным и использовать API ВК.В Интернете мне даже удалось найти пару библиотек, которые могли авторизоваться и выполнять функции из API. К сожалению, ни один из них мне не подошел, поэтому мне удалось за пару часов собрать собственный велосипед. Ладно, дело сделано, но тут я столкнулся с неприятным моментом, а именно с помощью текущей версии API невозможно получать сообщения со стены группы (или я не нашел как это сделать, что тоже вероятный).
Остается один вариант – разбирать страницы ВКонтакте самостоятельно.
С одной стороны, это не очень законно, с другой стороны, такой подход позволяет получить любую информацию, которую я могу увидеть прямо в браузере.
Попытка №2: парсить страницы напрямую!
Вход на сайт
Прежде всего я попробовал с httplib И URLlib получить страницу входа.Все чудесно и чудесно.
Я только что обнаружил, что мне придется писать много некрасивого кода, а также работать с куками.
И как-то меня это очень расстроило.
Я начал искать замену.
И я нашел замечательную библиотеку механизировать , который замечательно сделал за меня всю неинтересную работу по созданию соединений, обработке сессий и кукисов и т.д. Итак, с помощью механизации получаем главную страницу ВКонтакте:
В качестве пояснения скажу, что на vkontakte.ru первая форма - это именно форма входа.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
С помощью механизации заполняем его и вуаля, мы авторизованы на сайте!
Получение важных сообщений со стены
Следующий код позволит нам получить страницу группы: 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. Список получателей можно прочитать из конфига или жестко запрограммировать один почтовый адрес, как это было в моем случае.
Что произошло в конце
На выходе имеем:- важные сообщения отправляются нам на электронную почту, то есть нет необходимости заходить в ВКонтакте и обновлять страницу самостоятельно
- опыт парсинга страниц
- чувство удовлетворения и гордости за себя
Например, для любителей GUI можно сделать форму для ввода логина и пароля.
Также можно парсить сообщения по имени автора (например, отправлять все сообщения от имени группы), обрабатывать теги внутри сообщений и т. д., т. п.
и т. п.
Опыт показывает, что не следует переоценивать частоту обновления страниц; все сообщения по-прежнему будут получены, а чрезмерная активность может привести к временному бану.
Вот и все.
Спасибо за внимание! УПД.
Перенесен из ВКонтакте на Python. Теги: #python #вконтакте #механизировать #python
-
Планшетный Пк – Лучшее Изобретение Века
19 Oct, 24 -
Gentoo: Миграция С Eudev На Mdev
19 Oct, 24 -
Сборник Бреда Про Мою Страну
19 Oct, 24 -
Выпущена Haiku R1 Alpha 4
19 Oct, 24