web-dev-qa-db-fra.com

Selenium: Comment injecter/exécuter un Javascript dans une page avant de charger/exécuter un autre script de la page?

J'utilise Selenium Python WebDriver afin de parcourir certaines pages. Je souhaite injecter un code javascript dans une page avant que tous les autres codes Javascript soient chargés et exécutés. D'autre part, j'ai besoin que mon code JS soit exécuté en tant que premier code JS de cette page. Y a-t-il un moyen de le faire avec Selenium?

Je l'ai googlé pendant quelques heures, mais je n'ai pas trouvé de réponse appropriée! 

20
Alex

Si vous ne pouvez pas modifier le contenu de la page, vous pouvez utiliser un proxy ou un script de contenu dans une extension installée dans votre navigateur. En le faisant dans Selenium, vous écririez du code l'injectant en tant que fils d'un élément existant, mais vous ne pourrez pas l'exécuter avant le chargement de la page (lorsque l'appel du pilote get() sera rendu.)

String name = (String) ((JavascriptExecutor) driver).executeScript(
    "(function () { ... })();" ...

La documentation laisse indéterminé le moment où le code commencerait à s'exécuter. Vous voudriez le faire avant que le DOM commence à se charger afin que la garantie ne puisse être satisfiable que par la route de script de contenu de proxy ou d'extension.

Si vous pouvez instrumenter votre page avec un harnais minimal, vous pouvez détecter la présence d'un paramètre de requête d'URL spécial et charger du contenu supplémentaire, mais vous devez le faire à l'aide d'un script en ligne. Pseudocode:

 <html>
    <head>
       <script type="text/javascript">
       (function () {
       if (location && location.href && location.href.indexOf("Selenium_TEST") >= 0) {
          var injectScript = document.createElement("script");
          injectScript.setAttribute("type", "text/javascript");

          //another option is to perform a synchronous XHR and inject via innerText.
          injectScript.setAttribute("src", URL_OF_EXTRA_SCRIPT);
          document.documentElement.appendChild(injectScript);

          //optional. cleaner to remove. it has already been loaded at this point.
          document.documentElement.removeChild(injectScript);
       }
       })();
       </script>
    ...
3
init_js

Si vous voulez injecter quelque chose dans le HTML d'une page avant qu'elle ne soit analysée et exécutée par le navigateur, je vous suggère d'utiliser un proxy tel que Mitmproxy

3
Jonathan

Il existe maintenant https://pypi.org/project/Selenium-wire/ qui facilite l’accès/la modification à toutes les demandes.

0
phk