在PHP Mink中选择没有id的表单元素?

时间:2016-05-26 11:46:27

标签: php mink

我正在尝试使用PHP Mink(安装在nodejs cannot find module 'zombie' with PHP mink上)。我正在尝试解析一个网页(我无法控制),它在表单中有一个这样的元素:

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

值得注意的是,此<input>既没有id也没有name,因此我找不到选择此元素的方法。

我宁愿避免使用XPath,因为我不想专门指定一个可以在将来很好地改变的层次结构路径。我最喜欢在表单中查找一个孩子,其中value属性的值为Do Submit!,但我不知道如何在Mink中指定它?

我创建了一个证明这一点的最小例子;这是HTML文件:

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>

...这是PHP文件:

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
?>

脚本输出:

$ 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

那么,如何在此HTML文件中选择/获取对此按钮元素的引用?

2 个答案:

答案 0 :(得分:1)

首先,您应该识别一个唯一的部分(如果有的话),然后识别您的元素。 以下是一些可能的选择器:

&#13;
&#13;
obj = Reservation.find(whatever_record_id_you_are_using).extras.where(id: 3)
&#13;
&#13;
&#13;

如果您在页面中只有一个唯一的输入,则可以删除&#34; my-form&#34;部分。 在任何情况下(xss,xpath),您都不必指定层次结构路径,这可能是自动化的不良做法。如果您知道它可能会更改/翻译,请尽量避免在选择器中使用文本。

答案 1 :(得分:0)

好吧,似乎XPath确实有用 - 而且我认为我设法找到一个查询,它不一定涉及从文档的根目录写下元素的整个路径;但我在XPath上真的很糟糕,所以我仍然希望有更合格的答案。无论如何,我所做的是将其添加到OP脚本中:

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

......输出:

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

......这就是我需要的......