import logging import random import threading from concurrent.futures import ThreadPoolExecutor from typing import Union from playwright.sync_api import sync_playwright import params from logs.LogSender import TYPE_EVENT_CHECK_RESULTS, LOG_SUBJECT_EVENT from notification.AcceptedResultPojo import get_accepted_result_from from notification.mailer import Mailer from pojo.ReserveResultPojo import ReserveResultPojo from pojo.ResultEnum import ResultEnum from proxy.proxy_type import ProxyType from src import definitions SORRY_SENTENCE_FR = "nous sommes sincèrement désolés de n'avoir pu vous satisfaire cette fois-ci" SORRY_SENTENCE_EN = "we are extremely sorry that we were not able to fulfill" NOT_AVAILABLE_CONTENT = "For more than 130 years, our House has offered its full expertise to satisfy" PENDING_SENTENCE = "Ce soir, entre 20:00 et 20:30, vous obtiendrez une réponse par e-mail." PENDING_SENTENCE_EN = "This evening between 20:00 and 20:30 you will receive a response by email." # URLs to ignore during checking results BLANK_URL = "about:blank" WELCOME_URL = "https://rendezvousparis.hermes.com/client/welcome" mailer = Mailer() class TlsPlaywright(threading.local): def __init__(self) -> None: self.playwright = sync_playwright().start() print("创建浏览器实例,线程: ", threading.current_thread().name) class ResultChecker: tls = TlsPlaywright() def __init__(self): self.logger = logging.getLogger("Worker") def load_page(self, playwright, proxy, url) -> Union[str, None]: try: self.browser = playwright.webkit.launch(headless=False, timeout=90000, proxy=proxy) device = random.choice(params.DEVICES) self.logger.info("模拟设备: " + device) pixel_2 = self.tls.playwright.devices[device] context = self.browser.new_context(**pixel_2, locale='fr-FR') self.page = context.new_page() # hide webdriver information self.page.add_init_script("""() => { Object.defineProperty(navigator,'webdriver',{get: () => undefined}); Object.defineProperty(navigator, 'platform', { get: () => { return "iPhone"; }}); } """) self.page.goto(url, timeout=90000) return self.page.content() except Exception as error: print(error) return None def run(self, reserve_pojo: ReserveResultPojo, firestore_collection, need_send_email=False): print("Launched worker in ", threading.current_thread().name) url = reserve_pojo.url print("url is " + url) content = None proxy = params.get_proxy(ProxyType.BRIGHT_DATA) while content is None: content = self.load_page(self.tls.playwright, proxy, url) proxy = params.get_proxy(ProxyType.BRIGHT_DATA) print(content) self.browser.close() print("Stopped worker in ", threading.current_thread().name) if SORRY_SENTENCE_FR in content: print("status is REFUSED") status = ResultEnum.REFUSED elif SORRY_SENTENCE_EN in content: print("status is REFUSED") status = ResultEnum.REFUSED elif PENDING_SENTENCE in content: print("status is PENDING") status = ResultEnum.PENDING elif PENDING_SENTENCE_EN in content: print("status is PENDING") status = ResultEnum.PENDING elif NOT_AVAILABLE_CONTENT in content: print("status is REFUSED") status = ResultEnum.REFUSED else: print("status is ACCEPTED") status = ResultEnum.ACCEPTED if need_send_email: # send email try: mailer.send_email(get_accepted_result_from(reserve_pojo)) except Exception as err: print(err) reserve_pojo.accepted = status firestore_collection.document(reserve_pojo.id).update({u'accepted': status.name}) definitions.mongo_store_manager.update_reserve_result(reserve_pojo.id, status) def check_results(): # get the list params.oracle_log_sender.send_log(msg="开始检查约会结果", subject=LOG_SUBJECT_EVENT, type=TYPE_EVENT_CHECK_RESULTS) db_manager = definitions.firebase_store_manager firestore_collection = db_manager.get_all_successful_items() reserve_list = definitions.mongo_store_manager.get_all_successful_items_for_day() print("size is " + str(len(reserve_list))) start_check(reserve_list, firestore_collection, False) reserve_list = definitions.mongo_store_manager.get_all_successful_items_for_day() start_check(reserve_list, firestore_collection, True) def start_check(reserve_list, firestore_collection, need_send_email: bool): count = 0 with ThreadPoolExecutor(max_workers=20) as executor: for reserve in reserve_list: count = count + 1 if reserve.accepted is None or ResultEnum.ACCEPTED.value == reserve.accepted: print("will check result") if reserve.url != BLANK_URL: if reserve.url != WELCOME_URL: executor.submit(ResultChecker().run, reserve, firestore_collection, need_send_email) else: print("status is " + reserve.accepted) print(count) # need to start at 21h00 if __name__ == '__main__': check_results()