Граємося з VK API та Python, частина 2: стежимо за користувачем

6 хв. читання

Добридень, пані та панове. Сьогодні ми продовжимо мучити Python та VK API. Я хотів трохи погратися сьогодні в детективів, але їх діяльність в нашій країні незаконна :(. Тому ми будемо служити державі і на хвильку станемо слідчими. Уявіть, що ви слідчий, якому довірили наглядати за однією підозрілою особою. Але ж ми не прості слідчі, ми слідчі-програмісти. А що програмісти люблять понад усе? Правильно, звалювати свою роботу на комп'ютер, тому сьогодні ми напишемо скрипт, який буде відстежувати, які пости лайкав деякий користувач VK.

Зміст

Але не спішіть хитро потирати руки, VK ми ламати не будемо і ніяку інфу, що не можна роздобути на сайті ми не отримаємо. Але все ж дані іноді виходять дуже цікаві. Почнемо!

login = ''
password = ''

vkapi = vk.API('4567667', login, password)

Тут, думаю, все ясно. Якщо ні, то гайда читати першу частину! А ми йдемо далі. Для зручності користування ми будемо приймати на вхід url або id користувача. Але для роботи з API нам потрібен цифровий id (коротке імя на латині, що ви бачите в адресі сторінки не підходить)

def getUserId(link):
    id = link
    if 'vk.com/' in link: # перевіряємо чи це посилання
        id = link.split('/')[-1]  # якщо так, то отримуємо його останню частину
    if not id.replace('id', '').isdigit(): # якщо в ньому після відтинання 'id' самі цифри — це й є id 
        id = vkapi.utils.resolveScreenName(screen_name=id)['object_id'] # якщо ні, дістаємо id за допомогою методу API
    else:
        id = id.replace('id', '')
    return int(id)

Як бачите, ми отримуємо id за допомогою методу utils.resolveScreenName. В розділі для розробників ще багато цукерочок, та й взагалі це головний посібник в роботі з API. Тепер, коли дістати id для нас не проблема, приступимо до самого збору інформації, але спочатку я розкажу, як ми будемо це робити.

  1. Cпочатку ми отримуємо список підписок користувача за допомогою методу users.getSubscriptions.
  2. З використанням цього списку формуємо його стрічку новин за допомогою методу newsfeed.get
  3. Проходимо по кожному посту і перевіряємо чи лайкав його наш користувач за допомогою методу likes.isLiked

Так як за один запит можна отримати тільки до 100 постів, то ми будемо робити декілька запитів, в кожному по 100 постів. Ну а тепер почнемо:

def getLikes(user_id, count): # count це кількість запитів (і кількість постів = 100*count постів)
    subscriptions_list = vkapi.users.getSubscriptions(user_id=user_id, extended=0)['groups']['items'] # підписки користувача
    groups_list = ['-' + str(x) for x in subscriptions_list] # формуємо список id, який потрібно передати в наступний метод

    posts = {}
    newsfeed = vkapi.newsfeed.get(filters='post', source_ids=', '.join(groups_list), count=100, timeout=10) # формуємо стрічку новин

    posts.update({x['post_id'] : x['source_id'] for x in newsfeed['items']}) # додаємо пости до словника в форматі id_посту : id_групи 
    next_from = newsfeed['next_from'] # потрібно для отримання наступної партії

    if count != 1: # якщо потрібно більше одного запиту — робимо остачу в циклі
        for c in range(count-1):
            newsfeed = vkapi.newsfeed.get(filters='post', source_ids=', '.join(groups_list), count=100, timeout=10, start_from=next_from)
    
            posts.update({x['post_id'] : x['source_id'] for x in newsfeed['items']})
            next_from = newsfeed['next_from']

Тепер в нас є словник з постами зі стрічки новин. Лишилося лише пройтися по ньому і перевірити чи не лайкав його користувач. Вам може бути не дуже зрозумілий трюк (милиця?) з циклом: чому ми 2 рази писали один і той самий код? Вся справа в полі next_from, як нам каже документація, воно потрібне щоб отримати наступну "пачку" новин, але нам його не дістати без попереднього виклику API. Не буду сперечатися, є більш елегантне рішення, але наша задача в доданні коду функціональності, а не елегантності. Ну а тепер перевіримо пости на лайки:

    ...
    liked_posts = []

    print('Лайкнуті пости:')
    for post in posts.items():
        try:
            isLiked = vkapi.likes.isLiked(user_id=user_id, item_id=post[0], type="post", owner_id=post[1], timeout=5)['liked']
        except Exception:
            print("ERROR!!! " + 'vk.com/wall{}_{}'.format(post[1], post[0]))
            isLiked = 0
        if isLiked:
            liked_posts.append('vk.com/wall{}_{}'.format(post[1], post[0]))
            print('vk.com/wall{}_{}'.format(post[1], post[0]))
        sleep(0.25)
    return liked_posts

Тут все ясно і без коментарів. Якщо вас цікавить нащо ми призупиняли виконування на 0.25 секунди кожну ітерацію, то це через те, що likes.isLiked виконується доволі швидко і щоб не робити занадто багато запитів (VK таке не любить) призупиняємо виконання.

Ну й, напевно, саме цікаве: давайте випробуємо наш скрипт. Вибирайте самого цікавого знайомого або красивого незнайомця і в розвідку! Я для тесту вибрав одного "щасливця" з тих, хто лайкнув пост про минулу частину в нашій групі. З етичних міркувань (так, в мене ще є трохи совісті) я не показую посилання на сторінку. Якщо ви впізнали себе — радійте, ви обраний ;)

user_id = input('Введіть id користувача або посилання на сторінку: ')
user_id = getUserId(user_id)
getLikes(user_id, 5) # Скануємо 5*100 = 500 постів

Вихідні дані

➜ python3 main.py
Введіть id користувача або посилання на сторінку: http://vk.com/id***
Лайкнуті пости:
vk.com/wall-20629724_803918
vk.com/wall-30598666_692030
vk.com/wall-20629724_803740
vk.com/wall-30598666_691833
vk.com/wall-74257906_1865
vk.com/wall-20629724_803582

Переглянути код повністю можна тут. А ще ви можете прийняти участь у голосуванні за наступну тему для статті тут.

Помітили помилку? Повідомте автору, для цього достатньо виділити текст з помилкою та натиснути Ctrl+Enter
Codeguida 6.2K
Приєднався: 7 місяців тому
Коментарі (0)

    Ще немає коментарів

Щоб залишити коментар необхідно авторизуватися.

Вхід / Реєстрація