PhantomJs : cliquer quelques part avant un screenshot

Discussion dans 'Développement d'un site Web ou d'une appli mobile' créé par sff, 17 Février 2017.

  1. sff
    sff WRInaute impliqué
    Inscrit:
    2 Février 2005
    Messages:
    525
    J'aime reçus:
    0
    Bonjour,

    Je souhaite faire quelques chose de normalement assez simple avec PhantomJS. Avant de prendre la capture d'écran je souhaite que PhantomJS clique sur une coordonnée (pas un élement, mais une coordonnée du genre X = 100 et Y = 200).

    La capture doit donc avoir lieu sur le site B.

    Voici mon explication :

    [​IMG]

    Voici mon code actuel qui ne fonctionne pas car la capture se fait toujours sur le site A :

    Code:
    page.open(address, settings, function () {
    	
     page.evaluate(function(){
            // click
            var e = document.createEvent('MouseEvents');
            e.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
            document.querySelector("a").dispatchEvent(e);
        });
    	
    	
    	page.render(output);
    	phantom.exit();
    	
    });
    Je vous remercie de l'aide
     
  2. sff
    sff WRInaute impliqué
    Inscrit:
    2 Février 2005
    Messages:
    525
    J'aime reçus:
    0
    J'ai également essayer en intégrant Jquery et en supposant que le lien contient une class "test' mais cela ne fonctionne pas non plus

    Code:
    page.open(address, settings, function () {
    	
      page.includeJs("http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js", function() {
    	  
        page.evaluate(function() {
           jQuery(".test").click();
        });
        	page.render(output);
    	phantom.exit();
      });
    });
    Voici les log console :

    Code:
    2017-02-17T19:02:38 [DEBUG] WebPage - evaluateJavaScript "(function() { return (function () {\n       jQuery(\".test\").click();\n    })(); })()"
    2017-02-17T19:02:38 [DEBUG] WebPage - evaluateJavaScript result QVariant(Invalid)
     
  3. niap
    niap WRInaute discret
    Inscrit:
    17 Octobre 2009
    Messages:
    139
    J'aime reçus:
    0
    Question bête : L'élément existe au moment où tu appelle click() ?
    Utilise peut-être $(document).ready()
    Tu as une page de test ?
     
  4. spout
    spout WRInaute accro
    Inscrit:
    14 Mai 2003
    Messages:
    8 811
    J'aime reçus:
    242
  5. sff
    sff WRInaute impliqué
    Inscrit:
    2 Février 2005
    Messages:
    525
    J'aime reçus:
    0
    Je me retrouve donc avec ceci :

    Code:
    page.open(address, settings, function(status) {
        // Check for page load success
        if (status !== "success") {
            console.log("Unable to access network");
        } else {
            // Wait for 'signin-dropdown' to be visible
            waitFor(function() {
                // Check in the page if a specific element is now visible
                return page.evaluate(function() {
                    document.getElementById("test").click(); // en imaginant un id test sur le href
                });
            }, function() {
               console.log("The sign-in dialog should be visible now.");
    		   page.render(output);
               phantom.exit();
            });
        }
    }); 
    Les 2 pages sont bien ouverte par Phantomjs, mais la capture est toujours sur le site A et non le B
     
  6. sff
    sff WRInaute impliqué
    Inscrit:
    2 Février 2005
    Messages:
    525
    J'aime reçus:
    0
    Hormis le fait que je n'arrive pas à faire une capture sur le deuxième site (ce qui n'est pas le plus important), je n'arrive egalement pas à générer un clic sur la page avec des coordonnée. Est ce que quelqu'un pourrait m'aider ?

    J'ai essayé ceci en utilisant SendEvent (http://phantomjs.org/api/webpage/method/send-event.html)

    mais ca ne fait aucun effet.

    Code:
    page.open(address, settings, function(status) {
        // Check for page load success
        if (status !== "success") {
            console.log("Unable to access network");
        } else {
    
            waitFor(function() {
           
                return page.evaluate(function() {
    			
    		
        // find element to send click to
        var element = document.querySelector( 'body' );
     
     
        // send click to element
    	 element.sendEvent('click', 0, 0, button='left');
    
    				
                });
            }, function() {
    
             page.render(output);
               phantom.exit();
            });
        }
    });
    Voici les logs d'erreur :

    Code:
     undefined:9
      :12
    2017-02-17T23:56:28 [DEBUG] WebPage - evaluateJavaScript result QVariant(Invalid)
    2017-02-17T23:56:28 [DEBUG] WebPage - evaluateJavaScript "(function() { return (function () {\n\t\t\t\n\t\t\n    // find element to send click to\n    var element = document.querySelector( 'body' );\n \n \n    // send click to element\n\t element.sendEvent('click', 0, 0, button='left');\n\n\t\t\t\t\n            })(); })()"
    TypeError: undefined is not a function (evaluating 'element.sendEvent('click', 0, 0, button='left')')
    

    Merci d'avance
     
  7. niap
    niap WRInaute discret
    Inscrit:
    17 Octobre 2009
    Messages:
    139
    J'aime reçus:
    0
    Tu peux obtenir un l'élément aux coordonnées X Y avec elementFromPoint et simuler un clic dessus.
    Si tu es sûr de tes coordonnées tu peux faire une fonction qui sera appelée toutes les xxx ms jusqu'à ce que l'élément soit disponible dan le DOM.
    Code:
    var zeTimer = window.setInterval(clickCheck, 500);
    function clickCheck(){
        var e = document.elementFromPoint(100, 100);
        if(e){
            clearInterval(zeTimer);
            var evt = document.createEvent('Events');
            evt.initEvent('click', true, false);
            e.dispatchEvent(evt);
        }
    }
    
     
  8. sff
    sff WRInaute impliqué
    Inscrit:
    2 Février 2005
    Messages:
    525
    J'aime reçus:
    0
    Merci niap je vais tester tout ca.
     
  9. sff
    sff WRInaute impliqué
    Inscrit:
    2 Février 2005
    Messages:
    525
    J'aime reçus:
    0
    Malheuresement les logs m'affiche une erreur :


    2017-02-18T19:40:31 [DEBUG] WebPage - evaluateJavaScript result QVariant(Invalid)

    Logs de la partie problématique :

    2017-02-18T19:40:31 [DEBUG] WebPage - evaluateJavaScript "(function() { return (function () {\n\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\nfunction clickCheck(){\n var e = document.elementFromPoint(50, 50);\n if(e){\n clearInterval(zeTimer);\n var evt = document.createEvent('Events');\n evt.initEvent('click', true, false);\n e.dispatchEvent(evt);\n }\n}\n\t\t\n\n\t\tvar zeTimer = window.setInterval(clickCheck, 500);\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t})(); })()"
    2017-02-18T19:40:31 [DEBUG] WebPage - evaluateJavaScript result QVariant(Invalid)


    Mon code :

    Code:
    page.open(address, settings, function(status) {
    	
    	// Check for page load success
    	page.includeJs("http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js", function() {
    		
    		if (status !== "success") {
    			console.log("==================Unable to access network==================");
    		} else {
    			// Wait for element to be visible
    			waitFor(function() {
    				// Check in the page if a specific element is now visible
    				
    				return page.evaluate(function() {
    
    					return $("body").is(":visible");
    					
    				});
    				
    			}, function() {
    				console.log("==================The element should be visible now.==================");
    				
    				
    				page.evaluate(function() {
    			
    					
    function clickCheck(){
        var e = document.elementFromPoint(50, 50);
        if(e){
            clearInterval(zeTimer);
            var evt = document.createEvent('Events');
            evt.initEvent('click', true, false);
            e.dispatchEvent(evt);
        }
    }
    		var zeTimer = window.setInterval(clickCheck, 500);				
    					
    				});				
    				
    				page.render(output);
    				phantom.exit();
    			});
    		}
    	})
    });
    Le problème se situe à partir de function clickCheck(){
     
  10. sff
    sff WRInaute impliqué
    Inscrit:
    2 Février 2005
    Messages:
    525
    J'aime reçus:
    0
    J'ai enfin réussi à lui faire cliquer une position avec ce code :

    Code:
    page.open(address, settings, function(status) {
    	
    	// Check for page load success
    	page.includeJs("http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js", function() {
    		
    		if (status !== "success") {
    			console.log("==================Unable to access network==================");
    		} else {
    			// Wait for element to be visible
    			waitFor(function() {
    				// Check in the page if a specific element is now visible
    				
    				return page.evaluate(function() {
    
    					return $("body").is(":visible");
    					
    				});
    				
    			}, function() {
    				console.log("==================The element should be visible now.==================");
    				
    				page.sendEvent('click', 50, 50, button='left');
    				
    				page.render(output);
    				phantom.exit();
    			});
    		}
    	})
    });
    Mais il ne veut pas ouvrir l'url cible, je ne comprends pas !

    Voici les logs :

     
  11. sff
    sff WRInaute impliqué
    Inscrit:
    2 Février 2005
    Messages:
    525
    J'aime reçus:
    0
    Bon finalement, j'ai enfin résolu le problème par moi même. Il suffisait de rajouter un timeout à la fin, sinon il n'a pas le temps d"ouvrir la nouvelle page. J'ai mi 10 secondes par précaution. En espérant que ça servent à certains car sur de nombreux forums, il y a ce bug qui est répertorié.

    Code:
    page.open(address, settings, function(status) {
    	
    	// Check for page load success
    	page.includeJs("http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js", function() {
    		
    		if (status !== "success") {
    			console.log("==================Unable to access network==================");
    		} else {
    			// Wait for element to be visible
    			waitFor(function() {
    				// Check in the page if a specific element is now visible
    				
    				return page.evaluate(function() {
    
    					return $("body").is(":visible");
    					
    				});
    				
    			}, function() {
    				console.log("==================The element should be visible now.==================");
    				console.log("==================Wait 10 seconds.==================");
    				
    				page.sendEvent('click', 50, 50, button='left');
    				
    
    				setTimeout(function(){ 
    
                                          console.log("==================Capture==================");
    
    					page.render(output);
    					phantom.exit();
    
    				}, 10000);				
    			});
    		}
    	})
    });
    La page complete :

    Code:
    "use strict";
    
    //function wait display element
    function waitFor(testFx, onReady, timeOutMillis) {
    	var maxtimeOutMillis = timeOutMillis ? timeOutMillis : 3000, //< Default Max Timout is 3s
    	start = new Date().getTime(),
    	condition = false,
    	interval = setInterval(function() {
    		if ( (new Date().getTime() - start < maxtimeOutMillis) && !condition ) {
    			// If not time-out yet and condition not yet fulfilled
    			condition = (typeof(testFx) === "string" ? eval(testFx) : testFx()); //< defensive code
    		} else {
    			if(!condition) {
    				// If condition still not fulfilled (timeout but condition is 'false')
    				console.log("'waitFor()' timeout");
    				phantom.exit(1);
    			} else {
    				// Condition fulfilled (timeout and/or condition is 'true')
    				console.log("'waitFor()' finished in " + (new Date().getTime() - start) + "ms.");
    				typeof(onReady) === "string" ? eval(onReady) : onReady(); //< Do what it's supposed to do once the condition is fulfilled
    				clearInterval(interval); //< Stop this interval
    			}
    		}
    	}, 250); //< repeat check every 250ms
    };
    
    
    var page = require('webpage').create(),
    system = require('system'),
    address, output, ref;
    
    page.settings.userAgent = 'Opera/9.80 (Android 2.2.2; Linux; Opera Tablet/ADR-1111101157; U; en) Presto/2.9.201 Version/11.50';
    
    address = system.args[1];
    output = system.args[2];
    ref = system.args[3]; //Option
    
    var settings = {
    headers: {
    		"Referer": "http://yahoo.com"
    	}
    };	
    
    
    page.open(address, settings, function(status) {
    	
    	// Check for page load success
    	page.includeJs("http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js", function() {
    		
    		if (status !== "success") {
    			console.log("==================Unable to access network==================");
    		} else {
    			// Wait for element to be visible
    			waitFor(function() {
    				// Check in the page if a specific element is now visible
    				
    				return page.evaluate(function() {
    
    					return $("body").is(":visible");
    					
    				});
    				
    			}, function() {
    				console.log("==================The element 'BODY' should be visible now.==================");
    				console.log("==================Wait 10 seconds.==================");			
    				
    				page.sendEvent('click', 50, 50, button='left');
    
    				setTimeout(function(){ 
    					
    					console.log("==================Capture.==================");
    
    					page.render(output);
    					phantom.exit();
    
    				}, 10000);
    			});
    		}
    	})
    });
     
  12. madri2
    madri2 WRInaute impliqué
    Inscrit:
    29 Décembre 2007
    Messages:
    655
    J'aime reçus:
    0
    y'a surement plus propre qu'attendre 10 secondes
     
  13. sff
    sff WRInaute impliqué
    Inscrit:
    2 Février 2005
    Messages:
    525
    J'aime reçus:
    0
    Si tu as la solution je suis preneur
     
  14. madri2
    madri2 WRInaute impliqué
    Inscrit:
    29 Décembre 2007
    Messages:
    655
    J'aime reçus:
    0
    j'ai jamais utilisé phantomjs
     
  15. sff
    sff WRInaute impliqué
    Inscrit:
    2 Février 2005
    Messages:
    525
    J'aime reçus:
    0
    Voila la solution : page.onLoadFinished va vérifier si la nouvelle page a fini de charger

    Code:
    page.open(address, settings, function(status) {
    	
    	// Check for page load success
    	page.includeJs("http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js", function() {
    		
    		if (status !== "success") {
    			
    			console.log("======================== > Unable to access network");
    			
    		} else {
    
    			// Wait for element to be visible			
    			waitFor(function() {
    				
    				// Check in the page if a specific element is now visible
    				return page.evaluate(function() {
    
    					return $("body").is(":visible");
    					
    				});
    				
    			}, function() {
    				console.log("======================== > The element 'BODY' should be visible now");		
    				console.log("======================== > Click");	
    				
    				page.sendEvent('click', 50, 50, button='left');
    				
    				page.onLoadFinished = function(status) {
    					
    					console.log('======================== > Load Finished: ' + status);
    					console.log("======================== > Capture");
    					
    					page.render(output);
    					phantom.exit();
    
    				};			
    			});
    		}
    	})
    });
     
Chargement...
Similar Threads - PhantomJs cliquer part Forum Date
PhantomJS : capture d'écrans sont noires Développement d'un site Web ou d'une appli mobile 21 Mars 2017
Problème avec PhantomJS Développement d'un site Web ou d'une appli mobile 16 Février 2017
Référencement Google AJAX, AngularJS, PhantomJS Crawl et indexation Google, sitemaps 30 Mars 2015
Cliquer sur un lien pour qu'un lecteur s'affiche Développement d'un site Web ou d'une appli mobile 20 Octobre 2011
Inciter ma communauté à cliquer sur le +1 de Google Administration d'un site Web 27 Septembre 2011
cliquer son site augmente le positionnement? intox ou pas? Débuter en référencement 27 Septembre 2010
Cliquer au travers un div (z-index) Développement d'un site Web ou d'une appli mobile 27 Juin 2009
Cliquer sur les backlinks Débuter en référencement 14 Avril 2009
Cliquer sur une pub pour rentrer dans le site Développement d'un site Web ou d'une appli mobile 8 Avril 2009
cliquer sur son site Débuter en référencement 30 Mars 2009
  1. Ce site utilise des cookies. En continuant à utiliser ce site, vous acceptez l'utilisation des cookies.
    Rejeter la notice