Рубрики
Без рубрики

Как я использовал Python, чтобы найти интересных людей, чтобы следовать на среднем

Автор оригинала: FreeCodeCapm Team.

Radu RaiCea.

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

Я определяю интересный пользователь как кто-то, кто из вашей сети, который активен, и который пишет ответы, которые обычно ценятся со средним сообществом.

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

Процесс был утомительным. И вот когда я вспомнил самый ценный урок, который я узнал во время моей последней стажировки:

Любая утомительная задача может и должна быть автоматизирована.

Я хотел, чтобы моя автоматизация сделала следующие вещи:

  1. Получить все Пользователи Из моих «следующих» списка
  2. Получить последние Сообщения каждого пользователя
  3. Получить все Ответы к каждому посту
  4. Отфильтровать отклики, которые старше 30 дней
  5. Отфильтровывайте ответы, которые имеют меньше минимального количества рекомендаций
  6. Получить Имя пользователя автор каждого ответа

Давайте начнем показывать

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

Кроме того, последнее изменение в API средних было более года назад. Не было никаких признаков недавнего развития.

Я понял, что придется полагаться на HTTP-запросы, чтобы получить мои данные, поэтому я начал ткать, используя мой Chrome devtools Отказ

Первая цель состояла в том, чтобы получить мой список последующих.

Я открыл мои Devtools и пошел на вкладку сети. Я отфиксировал все, кроме XHR Чтобы увидеть, где среда получает мой список последующих последующих. Я ударил кнопку перезагрузки на своей странице профиля и не получил ничего интересного.

Что, если я нажал кнопку следующих путей в моем профиле? Бинго.

Внутри ссылки я нашел очень большой JSON отклик. Это был хорошо отформатированный JSON, кроме как строки персонажей в начале ответа: ])} пока (1); < /x>

Я написал функцию, чтобы очистить это и повернуть JSON в словарь Python.

import json
def clean_json_response(response):    return json.loads(response.text.split('])}while(1);')[1])

Я нашел точку входа. Пусть кодирование начнется.

Получить все пользователи из моих следующих списков

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

В поисках способа получить идентификатор пользователя, я узнал что вы можете добавить ? формат = JSON большинству средних URL, чтобы получить ответ JSON с этой страницы. Я попробовал это на своей странице профиля.

О, посмотрите, есть идентификатор пользователя.

])}while(1);{"success":true,"payload":{"user":{"userId":"d540942266d0","name":"Radu Raicea","username":"Radu_Raicea",...

Я написал функцию, чтобы вытащить идентификатор пользователя из данного имени пользователя. Опять же, я должен был использовать clean_json_response Удалить нежелательные символы в начале ответа.

Я также сделал постоянную под названием Средний который содержит основу для всех средних URL.

import requests
MEDIUM = 'https://medium.com'
def get_user_id(username):
    print('Retrieving user ID...')
    url = MEDIUM + '/@' + username + '?format=json'    response = requests.get(url)    response_dict = clean_json_response(response)    return response_dict['payload']['user']['userId']

С идентификатором пользователя я запросил /_/API/пользователи//fol Снижение конечной точки и получила список пользователей из моих следующих списков.

Когда я сделал это в Devtools, я заметил, что имел только ответ JSON только восемь имена пользователей. Странный.

После нажатия на «Показать больше людей», – увидел, чего не хватало. Средние использует Пагинация для списка следующих

Пагистрация работает, указав Ограничить (Элементы на страницу) и к (первый элемент следующей страницы). Мне пришлось найти способ получить идентификатор этого следующего элемента.

В конце ответа JSON от /_/API/пользователи//fol Снижение, я видел интересный ключ.

..."paging":{"path":"/_/api/users/d540942266d0/followers","next":{"limit":8,"to":"49260b62a26c"}}},"v":3,"b":"31039-15ed0e5"}

Отсюда, написание цикла, чтобы получить все имена пользователей из моих следующих списков было легко.

def get_list_of_followings(user_id):
    print('Retrieving users from Followings...')        next_id = False    followings = []
    while True:
        if next_id:            # If this is not the first page of the followings list            url = MEDIUM + '/_/api/users/' + user_id                  + '/following?limit=8&to=' + next_id        else:            # If this is the first page of the followings list            url = MEDIUM + '/_/api/users/' + user_id + '/following'
        response = requests.get(url)        response_dict = clean_json_response(response)        payload = response_dict['payload']
        for user in payload['value']:            followings.append(user['username'])
        try:            # If the "to" key is missing, we've reached the end            # of the list and an exception is thrown            next_id = payload['paging']['next']['to']        except:            break
    return followings

Получение новейших постов от каждого пользователя

Как только у меня будет список пользователей, которые я следую, я хотел получить свои последние сообщения. Я мог бы сделать это с просьбой к https://medium.com/@/latest?forma T = JSON

Я написал функцию, которая принимает список пользователей и возвращает список идентификаторов посту для последних сообщений от всех имени пользователей на списке ввода.

def get_list_of_latest_posts_ids(usernames):
    print('Retrieving the latest posts...')
    post_ids = []
    for username in usernames:        url = MEDIUM + '/@' + username + '/latest?format=json'        response = requests.get(url)        response_dict = clean_json_response(response)
        try:            posts = response_dict['payload']['references']['Post']        except:            posts = []
        if posts:            for key in posts.keys():                post_ids.append(posts[key]['id'])
    return post_ids

Получать все ответы с каждого поста

С помощью списка сообщений я извлек все ответы, используя https://medium.com/_/api/posts//res побуждение

Эта функция принимает список идентификаторов сообщения и возвращает список ответов.

def get_post_responses(posts):
    print('Retrieving the post responses...')
    responses = []
    for post in posts:        url = MEDIUM + '/_/api/posts/' + post + '/responses'        response = requests.get(url)        response_dict = clean_json_response(response)        responses += response_dict['payload']['value']
    return responses

Фильтрация ответов

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

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

Я хотел, чтобы минимум был динамичным, поэтому я передал переменную по имени Рекомендовать_min вокруг.

Следующая функция принимает ответ и Рекомендовать_min Переменная. Он проверяет, соответствует ли ответ на этот минимальный ответ.

def check_if_high_recommends(response, recommend_min):    if response['virtuals']['recommends'] >= recommend_min:        return True

Я также хотел недавние ответы. Я отфильтровал ответы, которые были старше 30 дней, используя эту функцию.

from datetime import datetime, timedelta
def check_if_recent(response):    limit_date = datetime.now() - timedelta(days=30)    creation_epoch_time = response['createdAt'] / 1000    creation_date = datetime.fromtimestamp(creation_epoch_time)
    if creation_date >= limit_date:        return True

Получение имени пользователя автора каждого ответа

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

def get_user_ids_from_responses(responses, recommend_min):
    print('Retrieving user IDs from the responses...')
    user_ids = []
    for response in responses:        recent = check_if_recent(response)        high = check_if_high_recommends(response, recommend_min)
        if recent and high:            user_ids.append(response['creatorId'])
    return user_ids

Идентификаторы пользователя бесполезны, когда вы пытаетесь получить доступ к чему-то профилю. Я сделал эту следующую функцию Query /_/API/пользователи/ ID> Конечная точка, чтобы получить имена пользователей.

def get_usernames(user_ids):
    print('Retrieving usernames of interesting users...')
    usernames = []
    for user_id in user_ids:        url = MEDIUM + '/_/api/users/' + user_id        response = requests.get(url)        response_dict = clean_json_response(response)        payload = response_dict['payload']
        usernames.append(payload['value']['username'])
    return usernames

Положить все это вместе

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

def get_interesting_users(username, recommend_min):
    print('Looking for interesting users for %s...' % username)
    user_id = get_user_id(username)
    usernames = get_list_of_followings(user_id)
    posts = get_list_of_latest_posts_ids(usernames)
    responses = get_post_responses(posts)
    users = get_user_ids_from_responses(responses, recommend_min)
    return get_usernames(users)

Сценарий был окончательно готов! Чтобы запустить его, вы должны позвонить по трубопроводу.

interesting_users = get_interesting_users('Radu_Raicea', 10)print(interesting_users)

Наконец, я добавил возможность добавить результаты к CSV с временем времени.

import csv
def list_to_csv(interesting_users_list):    with open('recommended_users.csv', 'a') as file:        writer = csv.writer(file)
        now = datetime.now().strftime('%Y-%m-%d %H:%M:%S')        interesting_users_list.insert(0, now)                writer.writerow(interesting_users_list)
interesting_users = get_interesting_users('Radu_Raicea', 10)list_to_csv(interesting_users)

Исходный код проекта находится на Github Отказ

Если вы не знаете, Python, посмотрите TK ‘s Обучение Python: от нуля до героя Отказ

Если у вас есть предложения по другим критериям, которые делают пользователей интересными, пожалуйста Напишите их ниже!

В итоге…

  • Я сделал Питонский скрипт для среднего Отказ
  • Сценарий возвращает список интересных пользователей Активный и Опубликовать интересные ответы На последних постах людей вы следуете.
  • Вы можете взять пользователей из списка и запустить скрипт с их именем пользователя вместо вашего.

Проверьте мой грунтовка На лицензии с открытым исходным кодом и как добавить их в свои проекты!

Для получения дополнительных обновлений следуйте за мной на Twitter Отказ