Добридень, пані та панове. Ви, напевно, вже здогадалися, що ми знову будемо творити щось цікаве за допомогою Python та VK API? Сьогодні ми напишемо невеличкий скрипт, що буде зберігати деяку інформацію з аккаунту. Якщо точніше, то лайкнуті пости та фото, список груп і повідомлення. Також за допомогою його можна буде писати та читати повідомлення. Ви спитаєте навіщо? А тому що ми будемо зберігати їх з чужого аккаунту. Розкажу детальніше. Іноді буває потрібно (читай цікаво) поглянути на чиюсь сторінку зсередини: почитати повідомлення, подивитися, що людина лайкала. Звісно, можна якось роздобути логін та пароль та зайти на сайті, але (скажу по своєму досвіду) навіть самі наївні "дівчата з 5-Б класу" не дадуть його добровільно. А от з access_token все куди простіше, можна під приводом накручування лайків чи чого іншого підсунути свій додаток і потім отримати access_token. Але ж біда, з ним на сайт не зайдеш. От тут у пригоді і стане наша програма.
Зміст
- Частина 1: завантажуємо всі фото з альбому
- Частина 2: стежимо за користувачем
- Частина 3: а ви любите єнотів?
- Частина 4: пишемо повідомлення прямо з терміналу (і не тільки)
Невеличкий фокус. Отримати токен зі сторінки можна за цим посиланням. Просто скопіюйте його, в поле client_id
вставте id свого додатку, а в scope
потрібні дозволи.
Ну а тепер давайте писати код. Крім модулю vk ми ще будемо використовувати colorama для кольорового тексту в терміналі. Можливо, на стандартній віндовсній консолі не буде працювати, я точно не знаю, бо навіть під віндою (зараз на лінуксі) використовував ConEmu, чого і вам бажаю. Ні, серйозно, спробуйте, крута штука. Також для зручнішої роботи з кольорами та форматуванням тексту ми напишемо свою надбудову над str.format
.
from colorama import Fore, Style, init
from pprint import pformat
import vk
from time import sleep
import os, sys
formating = {"green": Fore.GREEN,
"red": Fore.RED,
"white": Fore.WHITE,
"blue": Fore.BLUE,
"cyan": Fore.CYAN,
"yellow": Fore.YELLOW,
"bold": Style.BRIGHT,
"reset": Style.RESET_ALL}
mes_statuses = {1: "{bold}{blue}прочитане{reset} ==".format(**formating),
0: "{bold}{red}непрочитане{reset} ==".format(**formating)}
term_size = 109 # ширина вікна терміналу
init() # запускаємо colorama
if sys.platform == 'win32': # бо смайлики викликають ексепшн
os.system('chcp 65001')
# Шаблони для автора повідомлення та автора пересланого повідомлення
MESSAGE_AUTHOR = "{cyan}{first_name} {last_name}{reset} == {green}(https://vk.com/id{bold}{red}{id}{reset}{green}){reset} == "
FWD_MESSAGE_AUTHOR = ">> {yellow}{first_name} {last_name}{reset} == {green}(https://vk.com/id{bold}{red}{id}{reset}{green}){reset}"
def format(str, *args, **kw): # власні милиці, без них ніяк
buf = kw.copy() if kw else {}
buf.update(formating)
return str.format(*args, **buf)
Як бачите, наш format
робить теж саме що й str.format
, тільки автоматично вставляє кольори, тобто можна писати так:
format("{red}Codeguida{reset}")
format("{green} Oleg is {}{reset}", "raccoon")
Зауважте, що теги потрібно закривати, один раз, тобто після {reset}
вивід стає звичайного кольору та стилю.
Ох, навіть не знаю з чого зараз почати. Давайте з самого цікавого, з повідомлень. Щоб не писати один і той самий код декілька разів ми напишемо допоміжну функцію для відображення повідомлень.
def printMessages(messages, outfile=sys.stdout):
for mes in messages:
if "from_id" in mes:
user = vkapi.users.get(user_ids=mes['from_id'])[0]
else:
user = vkapi.users.get(user_ids=mes['user_id'])[0]
print(format(MESSAGE_AUTHOR, **user), end='', file=outfile)
print(mes_statuses[mes['read_state']], file=outfile)
print(mes['body'], file=outfile)
if 'fwd_messages' in mes: # перевірка чи прикріплені до повідомлення переслані повідомлення та їх друк
for fwd_mes in mes['fwd_messages']:
fwd_user = vkapi.users.get(user_ids=fwd_mes['user_id'])[0]
print(format(FWD_MESSAGE_AUTHOR, **fwd_user), file=outfile)
print(">>> {body}".format(**fwd_mes), file=outfile)
sleep(0.25)
if 'attachments' in mes:
print(format("{yellow}{bold}Attachments:{reset}"), file=outfile)
for a in mes['attachments']:
print("=== Type: {type}".format(**a), file=outfile)
print(pformat(a), file=outfile)
print(format("{bold}{0}{reset}", "="*term_size))
sleep(0.25)
Як бачите, я особливо не переймався відображенням прикріплень. Все тому що вони мають дуже багато видів і кожен слід обробляти по різному, тому ми просто відображаємо словник, що характеризує це прикріплення (який ми отримали з сайту), в зручному форматі.
Тепер давайте напишемо функції для відображення списку діалогів та конкретного діалогу.
def showDialogs(**kw):
dialogs = vkapi.messages.getDialogs(**kw)
printMessages([i['message'] for i in dialogs['items']])
def showDialog(**kw):
messages = vkapi.messages.getHistory(**kw)
printMessages(messages['items'][::-1]) # друкуємо перевернутий список (новіші знизу)
Тут нічого складного нема, тому рухаємося далі. Потрібно ще ж написати функцію для відправлення повідомлення.
def sendMessage(**kw):
if 'user_id' in kw:
user = vkapi.users.get(user_ids=kw['user_id'], name_case='dat')[0]
print("Відправити повідомлення {first_name} {last_name}".format(**user))
if 'message' not in kw:
message = input(">> ")
vkapi.messages.send(message=message, **kw)
else:
vkapi.messages.send(**kw)
if 'user_id' in kw:
yn = input("Відкрити діалог з користувачем? [y,т/n,н][n]: ")
if 'yes' in yn.lower() or 'y' in yn.lower() or 'т' in yn.lower() or 'так' in yn.lower():
showDialog(vkapi, count=10, user_id=kw['user_id'])
Тут все теж доволі просто, але все ж трохи роз'яснень не завадить. sendMessage(**kw)
як і showDialogs(**kw)
та showDialog(**kw)
приймає аргументи по ключу так само як і відповідні методи VK API, тобто це лише обгортка над методами VK API. Якщо вказаний user_id
(бо відправити повідомлення можна і за допомогою screen_name
), то він друкує його ім'я та після відправлення пропонує відкрити діалог з ним.
На цьому функції для безпосередньої роботи з повідомленнями закінчуються, залишилися лише функції для копіювання даних. Давайте почнемо з лайків. Всі лайкнуті фото, пости та інше вк відображає на сторінці закладок, відповідно за допомогою методів API їх можна звідтіля дістати.
def copyiked(count=1, mode="posts"):
likes = ''
for i in range(count):
if mode == "posts":
liked = vkapi.fave.getPosts(count=100, offset=i*100)
elif mode == "photos":
liked = vkapi.fave.getPhotos(count=100, offset=i*100)
for like in liked['items']:
if mode == 'posts':
likes += "vk.com/wall{owner_id}_{id}\
".format(**like)
elif mode == "photos":
likes += "vk.com/photo{owner_id}_{id}\
".format(**like)
sleep(0.25)
return likes
Ми зберігаємо тільки фото або пости, бо зазвичай в них найцікавіша інформація. Остачу ви можете прикрутити самі. Трюк з циклом, думаю, уже для вас зрозумілий, але все ж повторю, що ми зберігаємо 100*count записів/фото. Отримання списку груп так взагалі вийшло мініатюрним.
def copyGroups(count):
groups = ''
raw = vkapi.groups.get(count=count, extended=1, fields="screen_name")
for group in raw['items']:
groups += 'vk.com/{screen_name}\
'.format(**group)
return groups
Зауважте, що групи видаються в такому порядку як користувач бачить їх на сайті, тобто ті що він відвідує частіше розташовані зверху. Ну а зараз найцікавіше: збереження історії листування в файл. По суті, там нема нічого нового, просто функція показу повідомлень, але запис іде не в термінал, а в файл.
def copyMessages(id, count, filename=None):
messages = []
user = vkapi.users.get(user_ids=id)[0]
cur_user = vkapi.users.get()[0]
users = {cur_user['id']: cur_user,
user['id']: user}
for i in range(count):
buf = vkapi.messages.getHistory(user_id=id, count=200, offset=i*200)
for m in buf['items']:
messages.append(m)
sleep(0.25)
messages = messages[::-1]
if filename == None:
f = open(str(id) + "-messages.txt", 'w', encoding='utf-8')
else:
f = open(filename, 'w', encoding='utf-8')
printMessages(messages, outfile=f)
f.close()
def loadMessagees(filename):
with open(filename, encoding='utf-8') as f:
print(f.read())
Але вона все ж трохи відрізняється. Вона розрахована на великі обсяги повідомлень, тому запам'ятовує імена та зв'язує їх з id в словнику, щоб щоразу не робити запит до VK, а так все те саме що й в функції printMessages
. Якщо ви відкриєте файл в текстовому редакторі то побачите якусь кашу з символів. Справа в тому що там зберігається всі коди кольорів, тому дивитися його краще через функцію loadMessages(filename)
.
На цьому все, грайтеся, та не переходьте на сторону зла :). Весь код доступний тут.
Ще немає коментарів