/
Arthur159
/
chat_bot_BLS
Обзор
Документация
Войти
/
Arthur159
/
chat_bot_BLS
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
main.py
417 строк
20 KB
Arthur159
upload files
02 июн 2025, 16:35
02 июн 2025, 16:35
b4c2ea2
Код
Авторство
О чём код?
import os import traceback from selenium.webdriver import ActionChains from selenium.webdriver.common.by import By import keyboard from PIL import Image import time import re from seleniumwire import webdriver from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from image_preprocessing import preprocess_image from image_preprocessing import delete_directory_contents from ready_model import ready_model from collections import Counter import requests import telebot # Создаем экземпляр бота API_TOKEN = '8035878669:AAH4L51eUDNByj38G51HPtPQQn-3nvuWELU' bot = telebot.TeleBot(API_TOKEN) # Словарь для хранения выбранного города user_city = {} # Обработчик команды /start @bot.message_handler(commands=['start']) def send_welcome(message): bot.reply_to(message, "Пожалуйста, выберите город для подачи документов:", reply_markup=create_city_keyboard()) # Функция для создания клавиатуры с городами в виде сетки def create_city_keyboard(): markup = telebot.types.ReplyKeyboardMarkup(resize_keyboard=True, one_time_keyboard=True) cities = [ ["St Petersburg", "Kazan"], ["Novosibirsk", "Yekaterinburg"], ["Moscow", "Nizhny Novgorod"], ["Rostov-on-Don", "Samara"] ] for row in cities: markup.add(*row) # Добавляем строки в клавиатуру return markup # Обработчик выбора города @bot.message_handler(func=lambda message: True) def handle_city_selection(message): user_city[message.chat.id] = message.text bot.reply_to(message, f"Начинаю проверку свободных слотов для города {message.text}...") main(message.text, message.chat.id) # Передаем выбранный город и ID чата def main(selected_city, chat_id): while True: driver = webdriver.Chrome() # Установка размера окна (ширина, высота) driver.set_window_size(1366, 768) coordinates_list = [] # Переменная для хранения словарей с координатами try: url = 'https://russia.blsportugal.com/Global/account/login' verify_button = '//*[@id="btnVerify"]' driver.get(url) #time.sleep(7) # Ожидание полной загрузки страницы WebDriverWait(driver, 10).until( lambda driver: driver.execute_script('return document.readyState') == 'complete' ) logo = driver.find_element(By.XPATH, '//div[@class="text-center"]') logo.click() time.sleep(2) keyboard.press('tab') time.sleep(1) keyboard.write('safinartur061@gmail.com') time.sleep(2) keyboard.press('tab') time.sleep(1) keyboard.write('Chronicle1961!') time.sleep(2) input_field = driver.find_element(By.XPATH, "//input[@id='moscowCheckbox']") input_field.click() time.sleep(3) # Прокрутка до кнопки button = driver.find_element(By.XPATH, verify_button) driver.execute_script("window.scrollTo(0, document.body.scrollHeight)") time.sleep(1) # Небольшая задержка, чтобы прокрутка завершилась button = driver.find_element(By.XPATH, verify_button) button.click() time.sleep(5) def handle_captcha(driver): response_captcha = False while response_captcha == False: # Для получения координат фрейма xpath_iframe = '//*[@id="popup_1"]/iframe' element = driver.find_element(By.XPATH, xpath_iframe) location = element.location size = element.size timestamp = time.strftime("%Y%m%d_%H%M%S") screenshot_path = f'screenshot_element_{timestamp}.png' element.screenshot(screenshot_path) print(f'Скриншот сохранен {screenshot_path}') full_screenshot = Image.open(screenshot_path) additional_segments = [ (43, 95, 92, 92), (154, 95, 92, 92), (263, 95, 92, 92), (43, 205, 92, 92), (154, 205, 92, 92), (263, 205, 92, 92), (43, 315, 92, 92), (154, 315, 92, 92), (263, 315, 92, 92), ] for index, (x, y, w, h) in enumerate(additional_segments): cropped_segment = full_screenshot.crop((x, y, x + w, y + h)) cropped_path = f'input_images/cropped_segment_{timestamp}_{index}.png' cropped_segment.save(cropped_path) print(f'Сегмент сохранен как {cropped_path}') # удаление скриншота os.remove(screenshot_path) # использование предобработчика изображений processed_image = preprocess_image() # Ожидание загрузки фрейма и переключение на него WebDriverWait(driver, 10).until( EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR, 'iframe.k-content-frame'))) # Получение HTML-кода фрейма frame_source = driver.page_source # Множество для отслеживания уникальных координат unique_coordinates = set() # Регулярное выражение для извлечения всех ID картинок image_ids = re.findall(r'(?<=style="padding:5px;"\ id=").*?(?=">)', frame_source) # Проход по каждому ID и извлечение координат for i, image_id in enumerate(image_ids): # Используем XPath для нахождения элемента по ID image_element = driver.find_element(By.XPATH, f'//*[@id="{image_id}"]') # Получаем координаты элемента location = image_element.location size = image_element.size # Формируем координаты (x, y, width, height) x = location['x'] y = location['y'] # Проверка на нулевые координаты if x == 0 and y == 0: continue # Пропускаем, если координаты равны нулю # Проверка на дублирующиеся координаты if (x, y) in unique_coordinates: continue # Пропускаем, если координаты уже есть в множестве # Добавляем уникальные координаты в множество unique_coordinates.add((x, y)) coordinates = { 'id': image_id, 'x': x, 'y': y, 'width': size['width'], 'height': size['height'], } # Добавляем в список coordinates_list.append(coordinates) # Сортируем список по координатам (сначала по y, затем по x) coordinates_list.sort(key=lambda item: (item['y'], item['x'])) print("Список координат:") for item in coordinates_list: print(item) # использование нейронной модели для разгадывания цифр result_numbers = ready_model() print(result_numbers) # Подсчет наиболее часто встречающегося числа count = Counter(result_numbers) most_common_number, _ = count.most_common(1)[0] # Получение индексов всех вхождений наиболее часто встречающегося числа indices = [i for i, number in enumerate(result_numbers) if number == most_common_number] # Выбор словарей, соответствующих индексам наиболее часто встречающегося числа result_dictionaries = [coordinates_list[i] for i in indices] # Вывод результатов print(f"Наиболее часто встречающееся число: {most_common_number}") print("Словари, соответствующие этому числу:") for d in result_dictionaries: print(d) for d in result_dictionaries: element_id = d['id'] x = d['x'] # Получаем координату x из словаря y = d['y'] # Получаем координату y из словаря try: # Находим элемент, на который нужно навести курсор element_to_hover = driver.find_element(By.XPATH, f'//*[@id="{element_id}"]') # Находим элемент, по которому нужно кликнуть element_to_click = driver.find_element(By.XPATH, f'//*[@id="{element_id}"]') # Создаем объект ActionChains actions = ActionChains(driver) # Наведение курсора и клик actions.move_to_element(element_to_hover).click(element_to_click).perform() time.sleep(2) # пауза между кликами except Exception as e: print(f'Не удалось кликнуть по элементу с ID {element_id}: {e}') clear_input_images = delete_directory_contents("input_images") clear_output_images = delete_directory_contents("output_images") # подтверждение ввода каптчи element_to_submit = driver.find_element(By.XPATH, f'//*[@id="submit"]') element_to_submit.click() # очистка списков и словарей result_dictionaries.clear() coordinates_list.clear() time.sleep(5) # проверка на успешно разгаданную каптчу try: driver.switch_to.default_content() # Ожидание появления диалогового окна dialog = WebDriverWait(driver, 10).until( EC.visibility_of_element_located((By.XPATH, '//*[@id="btnVerified"]')) ) response_captcha = True except Exception as e: print("Неверный ответ на каптчу, повторная попытка") keyboard.press('enter') time.sleep(5) driver.switch_to.default_content() time.sleep(5) print('Каптча успешно распознана') handle_captcha_1 = handle_captcha(driver) login = driver.find_element(By.XPATH, f'//*[@id="btnSubmit"]') login.click() time.sleep(5) url_visa = 'https://russia.blsportugal.com/Global/bls/VisaTypeVerification' driver.get(url_visa) # Ожидание полной загрузки страницы WebDriverWait(driver, 10).until( lambda driver: driver.execute_script('return document.readyState') == 'complete' ) button = driver.find_element(By.XPATH, verify_button) button.click() time.sleep(3) handle_captcha_2 = handle_captcha(driver) login = driver.find_element(By.XPATH, f'//*[@id="btnSubmit"]') login.click() time.sleep(5) # Извлечение текущего URL current_url = driver.current_url print(current_url) # Получение куков из Selenium cookies = driver.get_cookies() # Преобразование куков в формат, который принимает requests cookies_dict = {cookie['name']: cookie['value'] for cookie in cookies} # Печать куков для проверки print('Сформированные куки:', cookies_dict) # Запрос для получения RequestVerificationToken url = f'{current_url}' headers = { 'Host': 'russia.blsportugal.com', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:137.0) Gecko/20100101 Firefox/137.0', 'Accept': 'text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8', 'Accept-Language': 'ru-RU, ru;q=0.8, en-US;q=0.5, en;q=0.3', 'Accept-Encoding': 'gzip, deflate, br, zstd', 'Connection': 'keep-alive', 'Referer': 'https://russia.blsportugal.com/Global/bls/VisaTypeVerification', 'Upgrade-Insecure-Requests': '1', 'Sec-Fetch-Dest': 'document', 'Sec-Fetch-Mode': 'navigate', 'Sec-Fetch-Site': 'same-origin', 'Sec-Fetch-User': '?1', 'Priority': 'u=0, i' } # Выполнение GET-запроса response = requests.get(url, headers=headers, cookies=cookies_dict) # Проверка статуса ответа if response.status_code == 200: print('Запрос выполнен успешно!') #print('Ответ на запрос:', response.text) # Извлечение RequestVerificationToken pattern = r'(?<=RequestVerificationToken"\ type="hidden"\ value=")[\w\W]*?(?=")' match = re.search(pattern, response.text) if match: extracted_value = match.group(0) # Извлечение значения print('Получено значение RequestVerificationToken:', extracted_value) else: print('Значение RequestVerificationToken не найдено.') else: print('Ошибка при выполнении запроса:', response.status_code) # Выбор города city_checkbox = { "St Petersburg": "0566245a-7ba1-4b5a-b03b-3dd33e051f46", "Kazan": "889689b5-1099-4795-ac19-c9263da23252", "Novosibirsk": "e13f9dd4-3c5c-4872-9058-3f867018a870", "Yekaterinburg": "8457a52e-98be-4860-88fc-2ce11b80a75e", "Moscow": "138660df-f645-488f-8458-97186b17c7f9", "Nizhny Novgorod": "60d2df036755e8de168d8db7", "Rostov-on-Don": "8d780684-1524-4bda-b138-7c71a8591944", "Samara": "dfd461c6-425b-42d2-b6c4-12eb8c3f8cb8" } # Получаем ID города и сохраняем в переменную if selected_city in city_checkbox: selected_city_id = city_checkbox[selected_city] # Получаем ID из словаря # POST запрос для получения слотов url_2 = f'https://russia.blsportugal.com/Global/BLSAppointment/GetAvailableAppointmentDates?locationId={selected_city_id}&categoryId=5c2e8e01-796d-4347-95ae-0c95a9177b26&visaType=2d9312f0-1157-46c2-b4a7-7fccfdb1dbb4&visaSubType=ca31e8be-507b-4d1e-9b67-d966d9fafcfb&applicantCount=1&dataSource=WEB_BLS&missionId=7f87b99c-9cbd-470e-ba98-0d6f158d83f6' headers_2 = { 'Host': 'russia.blsportugal.com', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:137.0) Gecko/20100101 Firefox/137.0', 'Accept': 'text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8', 'Accept-Language': 'ru-RU, ru;q=0.8, en-US;q=0.5, en;q=0.3', 'Accept-Encoding': 'gzip, deflate, br, zstd', 'RequestVerificationToken': f'{extracted_value}', 'X-Requested-With': 'XMLHttpRequest', 'Origin': 'https://russia.blsportugal.com', 'Connection': 'keep-alive', 'Sec-Fetch-Dest': 'empty', 'Sec-Fetch-Mode': 'cors', 'Sec-Fetch-Site': 'same-origin', 'Content-Length': '0', } # Выполнение POST-запроса response_2 = requests.post(url_2, headers=headers_2, cookies=cookies_dict) # Проверка статуса ответа if response_2.status_code == 200: print('Запрос выполнен успешно!') #print('Ответ на запрос:', response_2.text) # Извлечение ближайшей даты свободного слота pattern_data = r'(?<=true,"DateText":").*?(?=")' match = re.search(pattern_data, response_2.text) if match: extracted_value = match.group(0) # Извлечение значения print('Найден ближайший свободный слот на дату:', extracted_value) # Отправка сообщения в Телеграм bot.send_message(chat_id, f'Найден ближайший свободный слот на дату: {extracted_value}') break else: print('Не найдено ни одного доступного слота.') driver.quit() # Закрываем браузер time.sleep(1800) # Ждем 30 минут перед повторной попыткой else: print('Ошибка при выполнении запроса:', response.status_code) except Exception as e: print(f'An error occurred: {e}') print(traceback.print_exc()) finally: driver.quit() if __name__ == "__main__": bot.polling(none_stop=True) # Запускаем бота