@@ -65,6 +65,7 @@ def enabled_scripts():
6565
6666 _USER_AGENT_OVERRIDE_PIGGYBACK_KEY = "_stealth_user_agent"
6767 _SEC_CH_UA_OVERRIDE_PIGGYBACK_KEY = "_stealth_sec_ch_ua"
68+ _STEALTH_APPLIED_KEY = "_playwright_stealth_applied"
6869
6970 def __init__ (
7071 self ,
@@ -206,6 +207,14 @@ def _evasion_scripts(self) -> str:
206207 if self .webgl_vendor :
207208 yield SCRIPTS ["webgl_vendor" ]
208209
210+ def warn_if_stealth_applied (self , obj : Any ) -> bool :
211+ if hasattr (obj , self ._STEALTH_APPLIED_KEY ):
212+ warnings .warn (
213+ "Stealth has already been applied to this page or context. Skipping duplicate application." ,
214+ )
215+ return True
216+ return False
217+
209218 def use_async (self , ctx : async_api .PlaywrightContextManager ) -> AsyncWrappingContextManager :
210219 """
211220 Instruments the playwright context manager.
@@ -229,12 +238,14 @@ def use_sync(self, ctx: sync_api.PlaywrightContextManager) -> SyncWrappingContex
229238 return SyncWrappingContextManager (self , ctx )
230239
231240 async def apply_stealth_async (self , page_or_context : Union [async_api .Page , async_api .BrowserContext ]) -> None :
232- if len (self .script_payload ) > 0 :
241+ if len (self .script_payload ) > 0 and not self . warn_if_stealth_applied ( page_or_context ) :
233242 await page_or_context .add_init_script (self .script_payload )
243+ setattr (page_or_context , self ._STEALTH_APPLIED_KEY , True )
234244
235245 def apply_stealth_sync (self , page_or_context : Union [sync_api .Page , sync_api .BrowserContext ]) -> None :
236- if len (self .script_payload ) > 0 :
246+ if len (self .script_payload ) > 0 and not self . warn_if_stealth_applied ( page_or_context ) :
237247 page_or_context .add_init_script (self .script_payload )
248+ setattr (page_or_context , self ._STEALTH_APPLIED_KEY , True )
238249
239250 def hook_playwright_context (self , ctx : Union [async_api .Playwright , sync_api .Playwright ]) -> None :
240251 """
@@ -293,14 +304,16 @@ def sync_hooked_method(*args, **kwargs) -> sync_api.Browser:
293304 def _generate_hooked_new_context (self , new_context_method : Callable , new_page_method : Callable ) -> Callable :
294305 async def hooked_new_context_async (* args , ** kwargs ):
295306 context = await new_context_method (
296- * args , ** (await self ._kwargs_new_page_context_with_patches_async (new_page_method , kwargs ))
307+ * args ,
308+ ** (await self ._kwargs_new_page_context_with_patches_async (new_page_method , kwargs )),
297309 )
298310 await self .apply_stealth_async (context )
299311 return context
300312
301313 def hooked_browser_method_sync (* args , ** kwargs ):
302314 context = new_context_method (
303- * args , ** (self ._kwargs_new_page_context_with_patches_sync (new_page_method , kwargs ))
315+ * args ,
316+ ** (self ._kwargs_new_page_context_with_patches_sync (new_page_method , kwargs )),
304317 )
305318 self .apply_stealth_sync (context )
306319 return context
@@ -376,7 +389,11 @@ async def get_user_agent_and_sec_ch_ua_async() -> Tuple[str, str]:
376389 await temp_page .close (reason = "playwright_stealth internal temp utility page" )
377390 sec_ch_ua = self ._get_greased_chrome_sec_ua_ch (stealth_user_agent )
378391 setattr (browser_instance , self ._SEC_CH_UA_OVERRIDE_PIGGYBACK_KEY , sec_ch_ua )
379- setattr (browser_instance , self ._USER_AGENT_OVERRIDE_PIGGYBACK_KEY , stealth_user_agent )
392+ setattr (
393+ browser_instance ,
394+ self ._USER_AGENT_OVERRIDE_PIGGYBACK_KEY ,
395+ stealth_user_agent ,
396+ )
380397 return stealth_user_agent , sec_ch_ua
381398
382399 new_kwargs = deepcopy (packed_kwargs )
@@ -417,7 +434,11 @@ def get_user_agent_and_sec_ch_ua_sync() -> Tuple[str, str]:
417434 sec_ch_ua = self ._get_greased_chrome_sec_ua_ch (stealth_user_agent )
418435 temp_page .close (reason = "playwright_stealth internal temp utility page" )
419436 setattr (browser_instance , self ._SEC_CH_UA_OVERRIDE_PIGGYBACK_KEY , sec_ch_ua )
420- setattr (browser_instance , self ._USER_AGENT_OVERRIDE_PIGGYBACK_KEY , stealth_user_agent )
437+ setattr (
438+ browser_instance ,
439+ self ._USER_AGENT_OVERRIDE_PIGGYBACK_KEY ,
440+ stealth_user_agent ,
441+ )
421442 return stealth_user_agent , sec_ch_ua
422443
423444 new_kwargs = deepcopy (packed_kwargs )
0 commit comments