@@ -660,7 +660,7 @@ def get_gui_element_position(driver, selector):
660
660
return (viewport_x , viewport_y )
661
661
662
662
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 ):
664
664
install_pyautogui_if_missing (driver )
665
665
import pyautogui
666
666
pyautogui = get_configured_pyautogui (pyautogui )
@@ -678,38 +678,79 @@ def uc_gui_click_x_y(driver, x, y, timeframe=0.25, uc_lock=True):
678
678
with gui_lock : # Prevent issues with multiple processes
679
679
pyautogui .moveTo (x , y , timeframe , pyautogui .easeOutQuad )
680
680
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
682
682
if "--debug" in sys .argv :
683
683
print (" <DEBUG> pyautogui.click(%s, %s)" % (x , y ))
684
684
pyautogui .click (x = x , y = y )
685
685
else :
686
686
# Called from a method where the gui_lock is already active
687
687
pyautogui .moveTo (x , y , timeframe , pyautogui .easeOutQuad )
688
688
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
690
690
if "--debug" in sys .argv :
691
691
print (" <DEBUG> pyautogui.click(%s, %s)" % (x , y ))
692
692
pyautogui .click (x = x , y = y )
693
693
694
694
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 ):
696
700
source = driver .get_page_source ()
697
701
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
700
704
):
701
705
return True
702
706
return False
703
707
704
708
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
708
746
install_pyautogui_if_missing (driver )
709
747
import pyautogui
710
748
pyautogui = get_configured_pyautogui (pyautogui )
749
+ i_x = None
750
+ i_y = None
711
751
x = None
712
752
y = None
753
+ visible_iframe = True
713
754
gui_lock = fasteners .InterProcessLock (
714
755
constants .MultiBrowser .PYAUTOGUILOCK
715
756
)
@@ -725,22 +766,54 @@ def uc_gui_click_cf(driver, frame="iframe", retry=False, blind=False):
725
766
page_actions .switch_to_window (
726
767
driver , driver .current_window_handle , 2 , uc_lock = False
727
768
)
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
728
787
if not is_in_frame or needs_switch :
729
788
# Currently not in frame (or nested frame outside CF one)
730
789
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 )
733
793
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
739
802
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
744
817
driver .switch_to .default_content ()
745
818
except Exception :
746
819
try :
@@ -751,46 +824,91 @@ def uc_gui_click_cf(driver, frame="iframe", retry=False, blind=False):
751
824
try :
752
825
if x and y :
753
826
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 )
755
828
except Exception :
756
829
pass
757
830
reconnect_time = (float (constants .UC .RECONNECT_TIME ) / 2.0 ) + 0.5
758
831
if IS_LINUX :
759
- reconnect_time = constants .UC .RECONNECT_TIME
832
+ reconnect_time = constants .UC .RECONNECT_TIME + 0.15
760
833
if not x or not y :
761
834
reconnect_time = 1 # Make it quick (it already failed)
762
835
driver .reconnect (reconnect_time )
763
836
if blind :
764
837
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 ):
766
839
with gui_lock : # Prevent issues with multiple processes
767
840
# Make sure the window is on top
768
841
page_actions .switch_to_window (
769
842
driver , driver .current_window_handle , 2 , uc_lock = False
770
843
)
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" ):
774
845
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
775
864
if blind :
776
865
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 )
778
867
else :
779
868
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 ):
781
870
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 )
785
872
driver .reconnect (reconnect_time )
786
873
787
874
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
+
788
905
def 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 ):
790
907
return
791
908
install_pyautogui_if_missing (driver )
792
909
import pyautogui
793
910
pyautogui = get_configured_pyautogui (pyautogui )
911
+ visible_iframe = True
794
912
gui_lock = fasteners .InterProcessLock (
795
913
constants .MultiBrowser .PYAUTOGUILOCK
796
914
)
@@ -806,16 +924,46 @@ def uc_gui_handle_cf(driver, frame="iframe"):
806
924
page_actions .switch_to_window (
807
925
driver , driver .current_window_handle , 2 , uc_lock = False
808
926
)
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
809
944
if not is_in_frame or needs_switch :
810
945
# Currently not in frame (or nested frame outside CF one)
811
946
try :
812
- driver .switch_to_frame (frame )
947
+ if visible_iframe :
948
+ driver .switch_to_frame (frame )
813
949
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
818
955
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
819
967
driver .execute_script ('document.querySelector("input").focus()' )
820
968
except Exception :
821
969
try :
@@ -829,7 +977,7 @@ def uc_gui_handle_cf(driver, frame="iframe"):
829
977
pass
830
978
reconnect_time = (float (constants .UC .RECONNECT_TIME ) / 2.0 ) + 0.5
831
979
if IS_LINUX :
832
- reconnect_time = constants .UC .RECONNECT_TIME
980
+ reconnect_time = constants .UC .RECONNECT_TIME + 0.15
833
981
driver .reconnect (reconnect_time )
834
982
835
983
@@ -4166,6 +4314,16 @@ def get_local_driver(
4166
4314
driver , * args , ** kwargs
4167
4315
)
4168
4316
)
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
+ )
4169
4327
driver .uc_gui_click_cf = (
4170
4328
lambda * args , ** kwargs : uc_gui_click_cf (
4171
4329
driver , * args , ** kwargs
0 commit comments