@@ -660,7 +660,7 @@ def get_gui_element_position(driver, selector):
660660 return (viewport_x , viewport_y )
661661
662662
663- def uc_gui_click_x_y (driver , x , y , timeframe = 0.25 , uc_lock = True ):
663+ def _uc_gui_click_x_y (driver , x , y , timeframe = 0.25 , uc_lock = False ):
664664 install_pyautogui_if_missing (driver )
665665 import pyautogui
666666 pyautogui = get_configured_pyautogui (pyautogui )
@@ -678,38 +678,79 @@ def uc_gui_click_x_y(driver, x, y, timeframe=0.25, uc_lock=True):
678678 with gui_lock : # Prevent issues with multiple processes
679679 pyautogui .moveTo (x , y , timeframe , pyautogui .easeOutQuad )
680680 if timeframe >= 0.25 :
681- time .sleep (0.0555 ) # Wait if moving at human-speed
681+ time .sleep (0.056 ) # Wait if moving at human-speed
682682 if "--debug" in sys .argv :
683683 print (" <DEBUG> pyautogui.click(%s, %s)" % (x , y ))
684684 pyautogui .click (x = x , y = y )
685685 else :
686686 # Called from a method where the gui_lock is already active
687687 pyautogui .moveTo (x , y , timeframe , pyautogui .easeOutQuad )
688688 if timeframe >= 0.25 :
689- time .sleep (0.0555 ) # Wait if moving at human-speed
689+ time .sleep (0.056 ) # Wait if moving at human-speed
690690 if "--debug" in sys .argv :
691691 print (" <DEBUG> pyautogui.click(%s, %s)" % (x , y ))
692692 pyautogui .click (x = x , y = y )
693693
694694
695- def on_a_cf_turnstile_page (driver ):
695+ def uc_gui_click_x_y (driver , x , y , timeframe = 0.25 ):
696+ _uc_gui_click_x_y (driver , x , y , timeframe = timeframe , uc_lock = True )
697+
698+
699+ def _on_a_cf_turnstile_page (driver ):
696700 source = driver .get_page_source ()
697701 if (
698- "//challenges.cloudflare.com" in source
699- or 'aria-label="Cloudflare"' in source
702+ 'data-callback="onCaptchaSuccess"' in source
703+ or "cf-turnstile-wrapper" in source
700704 ):
701705 return True
702706 return False
703707
704708
705- def uc_gui_click_cf (driver , frame = "iframe" , retry = False , blind = False ):
706- if not on_a_cf_turnstile_page (driver ):
707- return
709+ def _on_a_g_recaptcha_page (driver ):
710+ source = driver .get_page_source ()
711+ if (
712+ 'id="recaptcha-token"' in source
713+ or 'title="reCAPTCHA"' in source
714+ ):
715+ return True
716+ return False
717+
718+
719+ def _uc_gui_click_captcha (
720+ driver ,
721+ frame = "iframe" ,
722+ retry = False ,
723+ blind = False ,
724+ ctype = None ,
725+ ):
726+ _on_a_captcha_page = None
727+ if ctype == "cf_t" :
728+ if not _on_a_cf_turnstile_page (driver ):
729+ return
730+ else :
731+ _on_a_captcha_page = _on_a_cf_turnstile_page
732+ elif ctype == "g_rc" :
733+ if not _on_a_g_recaptcha_page (driver ):
734+ return
735+ else :
736+ _on_a_captcha_page = _on_a_g_recaptcha_page
737+ else :
738+ if _on_a_g_recaptcha_page (driver ):
739+ ctype = "g_rc"
740+ _on_a_captcha_page = _on_a_g_recaptcha_page
741+ elif _on_a_cf_turnstile_page (driver ):
742+ ctype = "cf_t"
743+ _on_a_captcha_page = _on_a_cf_turnstile_page
744+ else :
745+ return
708746 install_pyautogui_if_missing (driver )
709747 import pyautogui
710748 pyautogui = get_configured_pyautogui (pyautogui )
749+ i_x = None
750+ i_y = None
711751 x = None
712752 y = None
753+ visible_iframe = True
713754 gui_lock = fasteners .InterProcessLock (
714755 constants .MultiBrowser .PYAUTOGUILOCK
715756 )
@@ -725,22 +766,54 @@ def uc_gui_click_cf(driver, frame="iframe", retry=False, blind=False):
725766 page_actions .switch_to_window (
726767 driver , driver .current_window_handle , 2 , uc_lock = False
727768 )
769+ if ctype == "cf_t" :
770+ if (
771+ driver .is_element_present (".cf-turnstile-wrapper iframe" )
772+ or driver .is_element_present (
773+ '[data-callback="onCaptchaSuccess"] iframe'
774+ )
775+ ):
776+ pass
777+ else :
778+ visible_iframe = False
779+ if driver .is_element_present (".cf-turnstile-wrapper" ):
780+ frame = ".cf-turnstile-wrapper"
781+ elif driver .is_element_present (
782+ '[data-callback="onCaptchaSuccess"]'
783+ ):
784+ frame = '[data-callback="onCaptchaSuccess"]'
785+ else :
786+ return
728787 if not is_in_frame or needs_switch :
729788 # Currently not in frame (or nested frame outside CF one)
730789 try :
731- i_x , i_y = get_gui_element_position (driver , "iframe" )
732- driver .switch_to_frame (frame )
790+ i_x , i_y = get_gui_element_position (driver , frame )
791+ if visible_iframe :
792+ driver .switch_to_frame (frame )
733793 except Exception :
734- if driver .is_element_present ("iframe" ):
735- i_x , i_y = get_gui_element_position (driver , "iframe" )
736- driver .switch_to_frame ("iframe" )
737- else :
738- return
794+ if visible_iframe :
795+ if driver .is_element_present ("iframe" ):
796+ i_x , i_y = get_gui_element_position (driver , "iframe" )
797+ driver .switch_to_frame ("iframe" )
798+ else :
799+ return
800+ if not i_x or not i_y :
801+ return
739802 try :
740- selector = "span"
741- element = driver .wait_for_element_present (selector , timeout = 2.5 )
742- x = i_x + element .rect ["x" ] + int (element .rect ["width" ] / 2 ) + 1
743- y = i_y + element .rect ["y" ] + int (element .rect ["height" ] / 2 ) + 1
803+ if visible_iframe :
804+ selector = "span"
805+ if ctype == "g_rc" :
806+ selector = "span.recaptcha-checkbox"
807+ element = driver .wait_for_element_present (
808+ selector , timeout = 2.5
809+ )
810+ x = i_x + element .rect ["x" ] + int (element .rect ["width" ] / 2 )
811+ x += 1
812+ y = i_y + element .rect ["y" ] + int (element .rect ["height" ] / 2 )
813+ y += 1
814+ else :
815+ x = i_x + 34
816+ y = i_y + 34
744817 driver .switch_to .default_content ()
745818 except Exception :
746819 try :
@@ -751,46 +824,91 @@ def uc_gui_click_cf(driver, frame="iframe", retry=False, blind=False):
751824 try :
752825 if x and y :
753826 sb_config ._saved_cf_x_y = (x , y )
754- uc_gui_click_x_y (driver , x , y , timeframe = 0.842 , uc_lock = False )
827+ _uc_gui_click_x_y (driver , x , y , timeframe = 0.95 )
755828 except Exception :
756829 pass
757830 reconnect_time = (float (constants .UC .RECONNECT_TIME ) / 2.0 ) + 0.5
758831 if IS_LINUX :
759- reconnect_time = constants .UC .RECONNECT_TIME
832+ reconnect_time = constants .UC .RECONNECT_TIME + 0.15
760833 if not x or not y :
761834 reconnect_time = 1 # Make it quick (it already failed)
762835 driver .reconnect (reconnect_time )
763836 if blind :
764837 retry = True
765- if retry and x and y and on_a_cf_turnstile_page (driver ):
838+ if retry and x and y and _on_a_captcha_page (driver ):
766839 with gui_lock : # Prevent issues with multiple processes
767840 # Make sure the window is on top
768841 page_actions .switch_to_window (
769842 driver , driver .current_window_handle , 2 , uc_lock = False
770843 )
771- driver .switch_to_frame ("iframe" )
772- if driver .is_element_visible ("#success-icon" ):
773- driver .switch_to .parent_frame ()
844+ if not driver .is_element_present ("iframe" ):
774845 return
846+ else :
847+ try :
848+ driver .switch_to_frame (frame )
849+ except Exception :
850+ try :
851+ driver .switch_to_frame ("iframe" )
852+ except Exception :
853+ return
854+ checkbox_success = None
855+ if ctype == "cf_t" :
856+ checkbox_success = "#success-icon"
857+ elif ctype == "g_rc" :
858+ checkbox_success = "span.recaptcha-checkbox-checked"
859+ else :
860+ return # If this line is reached, ctype wasn't set
861+ if driver .is_element_visible ("#success-icon" ):
862+ driver .switch_to .parent_frame (checkbox_success )
863+ return
775864 if blind :
776865 driver .uc_open_with_disconnect (driver .current_url , 3.8 )
777- uc_gui_click_x_y (driver , x , y , timeframe = 1.05 , uc_lock = False )
866+ _uc_gui_click_x_y (driver , x , y , timeframe = 1.05 )
778867 else :
779868 driver .uc_open_with_reconnect (driver .current_url , 3.8 )
780- if on_a_cf_turnstile_page (driver ):
869+ if _on_a_captcha_page (driver ):
781870 driver .disconnect ()
782- uc_gui_click_x_y (
783- driver , x , y , timeframe = 1.05 , uc_lock = False
784- )
871+ _uc_gui_click_x_y (driver , x , y , timeframe = 1.05 )
785872 driver .reconnect (reconnect_time )
786873
787874
875+ def uc_gui_click_captcha (driver , frame = "iframe" , retry = False , blind = False ):
876+ _uc_gui_click_captcha (
877+ driver ,
878+ frame = frame ,
879+ retry = retry ,
880+ blind = blind ,
881+ ctype = None ,
882+ )
883+
884+
885+ def uc_gui_click_rc (driver , frame = "iframe" , retry = False , blind = False ):
886+ _uc_gui_click_captcha (
887+ driver ,
888+ frame = frame ,
889+ retry = retry ,
890+ blind = blind ,
891+ ctype = "g_rc" ,
892+ )
893+
894+
895+ def uc_gui_click_cf (driver , frame = "iframe" , retry = False , blind = False ):
896+ _uc_gui_click_captcha (
897+ driver ,
898+ frame = frame ,
899+ retry = retry ,
900+ blind = blind ,
901+ ctype = "cf_t" ,
902+ )
903+
904+
788905def uc_gui_handle_cf (driver , frame = "iframe" ):
789- if not on_a_cf_turnstile_page (driver ):
906+ if not _on_a_cf_turnstile_page (driver ):
790907 return
791908 install_pyautogui_if_missing (driver )
792909 import pyautogui
793910 pyautogui = get_configured_pyautogui (pyautogui )
911+ visible_iframe = True
794912 gui_lock = fasteners .InterProcessLock (
795913 constants .MultiBrowser .PYAUTOGUILOCK
796914 )
@@ -806,16 +924,46 @@ def uc_gui_handle_cf(driver, frame="iframe"):
806924 page_actions .switch_to_window (
807925 driver , driver .current_window_handle , 2 , uc_lock = False
808926 )
927+ if (
928+ driver .is_element_present (".cf-turnstile-wrapper iframe" )
929+ or driver .is_element_present (
930+ '[data-callback="onCaptchaSuccess"] iframe'
931+ )
932+ ):
933+ pass
934+ else :
935+ visible_iframe = False
936+ if driver .is_element_present (".cf-turnstile-wrapper" ):
937+ frame = ".cf-turnstile-wrapper"
938+ elif driver .is_element_present (
939+ '[data-callback="onCaptchaSuccess"]'
940+ ):
941+ frame = '[data-callback="onCaptchaSuccess"]'
942+ else :
943+ return
809944 if not is_in_frame or needs_switch :
810945 # Currently not in frame (or nested frame outside CF one)
811946 try :
812- driver .switch_to_frame (frame )
947+ if visible_iframe :
948+ driver .switch_to_frame (frame )
813949 except Exception :
814- if driver .is_element_present ("iframe" ):
815- driver .switch_to_frame ("iframe" )
816- else :
817- return
950+ if visible_iframe :
951+ if driver .is_element_present ("iframe" ):
952+ driver .switch_to_frame ("iframe" )
953+ else :
954+ return
818955 try :
956+ found_checkbox = False
957+ for i in range (10 ):
958+ pyautogui .press ("\t " )
959+ time .sleep (0.02 )
960+ active_element_css = js_utils .get_active_element_css (driver )
961+ if active_element_css == "div.cf-turnstile-wrapper" :
962+ found_checkbox = True
963+ break
964+ time .sleep (0.02 )
965+ if not found_checkbox :
966+ return
819967 driver .execute_script ('document.querySelector("input").focus()' )
820968 except Exception :
821969 try :
@@ -829,7 +977,7 @@ def uc_gui_handle_cf(driver, frame="iframe"):
829977 pass
830978 reconnect_time = (float (constants .UC .RECONNECT_TIME ) / 2.0 ) + 0.5
831979 if IS_LINUX :
832- reconnect_time = constants .UC .RECONNECT_TIME
980+ reconnect_time = constants .UC .RECONNECT_TIME + 0.15
833981 driver .reconnect (reconnect_time )
834982
835983
@@ -4166,6 +4314,16 @@ def get_local_driver(
41664314 driver , * args , ** kwargs
41674315 )
41684316 )
4317+ driver .uc_gui_click_captcha = (
4318+ lambda * args , ** kwargs : uc_gui_click_captcha (
4319+ driver , * args , ** kwargs
4320+ )
4321+ )
4322+ driver .uc_gui_click_rc = (
4323+ lambda * args , ** kwargs : uc_gui_click_rc (
4324+ driver , * args , ** kwargs
4325+ )
4326+ )
41694327 driver .uc_gui_click_cf = (
41704328 lambda * args , ** kwargs : uc_gui_click_cf (
41714329 driver , * args , ** kwargs
0 commit comments