Всем привет
Давненько не писал статьи, да и этот пост, собственно, не является чем-то обучающим. А суть вот в чем.
Завалялось на компьютере около 80-100 логов, которые здешние ребята раздают(за что им очередное спасибо). Решил для своих нужд написать парсер, который разбирает сookies для vk.com и записывает в удобные для меня структуры. Инструмент написан на коленке, за пару-тройку вечеров. Он не претендует на звание верного помощника, однако, мне сослужил отлично.
Из сотни логов (2245 файлов - ВСЕ txt+log) он достал 77 куки вк из которых 30 были полными(наличие полей: remixsid, remixstid, remixusid, l, p).
Валидными были всего три, но это уже не вина парсера, так как почти все логи с куками были пабликами.
Также дополнил код методом по сбору токенов(собрал 42, 10 из которых из oauth.vk.com)
Делюсь с вами исходником парсера, может кому-нибудь также как и мне будет полезно.
Опять таки, warning: разрабатывал под себя, не претендует на конкуренцию с программами-скриптами по этой тематике.
Код предоставляю с комментариями, должно быть все понятно. Список requirements пустой - все библиотеки стандартные.
Пример запуска:
Примеры вывода:
Полученные файлы:
Полученный код в прикрепленных файлах.
Продолжение: Получение токена из сессии
Давненько не писал статьи, да и этот пост, собственно, не является чем-то обучающим. А суть вот в чем.
Завалялось на компьютере около 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"
]
Полученный код в прикрепленных файлах.
Продолжение: Получение токена из сессии
Вложения
Последнее редактирование: