2016-05-26 9 views
0

Ich experimentiere mit PHP Mink (installiert als nodejs cannot find module 'zombie' with PHP mink). Ich versuche, eine Webseite zu analysieren (die ich keine Kontrolle haben), die ein Element wie dies in einer Form hat:Auswählen eines Formularelements ohne ID in PHP Mink?

<input tabindex="5" value="Do Submit!" class="my_btn my_btn_2" type="submit"></input> 

Bemerkenswerter eine Art und Weise, diese <input> hat weder id noch name, und so kann ich nicht finden um dieses Element auszuwählen.

Ich würde es lieber vermeiden, XPath zu verwenden, weil ich nicht explizit einen Hierarchiepfad angeben möchte, der sich in Zukunft sehr wohl ändern kann. Ich möchte am besten ein Kind in dem Formular nachschlagen, das ein value Attribut mit Wert Do Submit! hat, aber ich weiß nicht, wie man das in Mink angibt?

Ich habe ein minimales Beispiel erstellt, das das demonstriert; hier ist die HTML-Datei:

selbtnnoid.htm

<html> 
<head> 
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
    <style type="text/css"> 
     .my_form { 
      width: 50%; 
      border: 2px solid red; 
     } 
     .my_label { 
      font-size: large; 
     } 
     .my_input_2 { 
      font-size: medium; 
     } 
     .my_btn { 
      background-color: yellow; 
     } 
     .my_btn_2 { 
      font-size: large; 
     } 
    </style> 
</head> 
<body> 
    <h1>Hello World!</h1> 
    <p>Here is the form:</p> 
    <form method="post" action="wherever.php" id="my-form" class="my_form"> 
     <h1>Some form here:</h1> 
     <p> 
      <label for="my-input-txt"> 
       <span class="my_label">Some data:</span> 
       <input name="my-input-txt" id="my-input-txt" placeholder=" Enter data. " class="my_input_2" tabindex="1" type="text"></input> 
      </label> 
     </p> 
     <p> 
      <input tabindex="5" value="Do Submit!" class="my_btn my_btn_2" type="submit"></input> 
     </p> 
    </form> 
</body> 
</html> 

... und hier ist die PHP-Datei:

test_php_mink_selbtnnoid.php

<?php 

$nodeModPath = "/home/USERNAME/.nvm/versions/node/v4.0.0/lib/node_modules"; 
putenv("NODE_PATH=".$nodeModPath); # doesn't really help; use setNodeModulesPath 

# composer autoload for mink: 
require_once __DIR__ . '/vendor/autoload.php'; 

$zsrv = new \Behat\Mink\Driver\NodeJS\Server\ZombieServer(); 
$zsrv->setNodeModulesPath($nodeModPath . "/"); # needs to end with a trailing '/' 
$driver = new \Behat\Mink\Driver\ZombieDriver($zsrv); 
$session = new \Behat\Mink\Session($driver); 

// start the session 
$session->start(); 

//~ $session->visit('selbtnnoid.htm'); // nope; status code: 0 if just called locally 
//~ $session->visit('file:///path/to/selbtnnoid.htm'); // nope; Error: listen EADDRINUSE 127.0.0.1:8124 
$session->visit('http://localhost:8090/selbtnnoid.htm'); // run php -S localhost:8090 in the folder with these two files 

echo " current URL: " . $session->getCurrentUrl() ."\n"; 
echo " status code: " . $session->getStatusCode() ."\n"; 

$page = $session->getPage(); 
$myForm = $page->findById("my-form"); 
$myInput = $myForm->findField("my-input-txt"); 

# check if we have the element: // yes, displays 'my input tag is: input' 
echo "my input tag is: ". $myInput->getTagName() ."\n"; 

# try to get the button: 
$myBtn = $myForm->findField("Do Submit!"); 
echo "button selected by value is: " . var_export($myBtn, true) ."\n"; // NULL 

$myBtn = $myForm->find('css', 'my_btn'); 
echo "button selected by css is: " . var_export($myBtn, true) ."\n"; // NULL 
?> 

Die Skript-Ausgänge:

$ php test_php_mink_selbtnnoid.php 
    current URL: http://localhost:8090/selbtnnoid.htm 
    status code: 200 
my input tag is: input 
button selected by value is: NULL 
button selected by css is: NULL 

Also, wie kann ich einen Verweis auf diese Schaltfläche Element in dieser HTML-Datei auswählen/erhalten?

Antwort

1

Zuerst Sollte ein eindeutiger Abschnitt identifiziert werden, identifizieren Sie danach Ihr Element. Hier sind einige mögliche Selektoren:

css: #my-form input[type=submit] 
 
css: #my-form input.my_btn 
 
css: #my-form input.my_btn_2 
 

 
xpath: //*[@id='my-form']//input[@type='submit'] 
 
xpath: //*[@id='my-form']//input[contains(@class, 'my_btn')]

, wenn Sie nur eine einzige Eingabe in der Seite haben, können Sie "my-Form" Teil entfernen. Sie müssen auf keinen Fall einen Hierarchiepfad angeben (xss, xpath). Dies ist möglicherweise eine schlechte Vorgehensweise für die Automatisierung. Versuchen Sie auch, Text in Selektoren zu vermeiden, wenn Sie wissen, dass er sich ändern/übersetzen kann.

+0

Danke dafür, @lauda - ich habe wirklich keine anderen eindeutigen Identifikatoren, so dass der Wert-Text wirklich das einzige Ding ist, das ich für wählen kann; Obwohl ich weiß, dass die Klasse Selektor enthält, kann das nützlich sein. – sdbbs

0

Nun, es scheint XPath funktioniert - und ich denke, ich habe es geschafft, eine Abfrage zu finden, die nicht unbedingt den gesamten Pfad zu Element aus dem Stamm des Dokuments schreiben; Aber ich bin wirklich schlecht in XPath, also hoffe ich immer noch auf eine bessere Antwort. Wie auch immer, was ich tat, war dieses Skript zum OP hinzufügen:

$myBtn = $myForm->find('xpath', '//*[@value="Do Submit!"]'); 
echo "button selected by xpath is: " . $myInput->getTagName() . "; with 'value': " . $myBtn->getAttribute('value') ."\n"; 

... die Ausgänge:

button selected by xpath is: input; with 'value': Do Submit! 

... das ist, was ich brauchte ...

Verwandte Themen