Механизм Python - две кнопки типа «отправить» - PullRequest
27 голосов
/ 09 апреля 2009

У меня есть скрипт механизации, написанный на python, который заполняет веб-форму и должен нажать кнопку «Создать». Но есть проблема, форма имеет две кнопки. Один для «добавить прикрепленный файл» и один для «создать». Оба типа «отправить», и кнопка присоединения является первой в списке. Поэтому, когда я выбираю форум и выполняю br.submit (), он нажимает кнопку «присоединить» вместо «создать». Extensive Googling не дал ничего полезного для выбора определенной кнопки в форме. Кто-нибудь знает какие-либо методы пропуска первой кнопки «Отправить» и нажатия второй?

Ответы [ 4 ]

21 голосов
/ 06 ноября 2009

Я безуспешно пытался использовать параметр nr.

Мне удалось заставить его работать с сочетанием параметров имени и метки, где «метка», кажется, соответствует «значению» в HTML:

Вот две мои кнопки отправки:

<input type="submit" name="Preview" value="Preview" />
<input type="submit" name="Create" value="Create New Page" />

... и вот код, который щелкает первый, возвращается, а затем нажимает второй:

from mechanize import Browser
self.br = Browser()
self.br.open('http://foo.com/path/to/page.html')
self.br.select_form(name='my_form')
self.br['somefieldname'] = 'Foo'
submit_response = self.br.submit(name='Preview', label='Preview')
self.br.back()
self.br.select_form(name='my_form')
self.br['somefieldname'] = 'Bar'
submit_response = self.br.submit(name='Create', label='Create New Page')

Есть вариант, который также работает для меня, где «имя» кнопки отправки такое же, как:

<input type="submit" name="action" value="Preview" />
<input type="submit" name="action" value="Save" />
<input type="submit" name="action" value="Cancel" />

и

self.br.select_form(name='my_form')
submit_response = self.br.submit(name='action', label='Preview')
self.br.back()
submit_response = self.br.submit(name='action', label='Save')

ВАЖНОЕ ПРИМЕЧАНИЕ - я только смог заставить работать любой из этих кодов с несколькими кнопками отправки после очистки некоторого HTML-кода на остальной части страницы.

В частности, у меня не могло быть <br/> - вместо этого я должен был иметь <br /> ... и, что еще меньше смысла, у меня не могло быть ничего между двумя кнопками отправки.

Меня бесконечно разочаровало, что ошибка механизации / ClientForm, за которой я охотился более двух часов, сводилась к следующему:

<tr><td colspan="2"><br/><input type="submit" name="Preview" value="Preview" />&nbsp;<input type="submit" name="Create" value="Create New Page" /></td></tr>

(все в одной строке) не сработало, но

<tr><td colspan="2"><br />
<input type="submit" name="Preview" value="Preview" />
<input type="submit" name="Create" value="Create New Page" /></td></tr>

работал нормально (на нескольких строках, что также не должно было иметь значения).

Мне нравится механизировать, потому что его было легко установить (просто скопируйте файлы в мой каталог include), и потому что его довольно просто использовать, но если я не пропустил что-то серьезное, я думаю, что ошибки вроде этого ужасны - Я не могу придумать вескую причину, по которой первый пример должен потерпеть неудачу, а второй должен работать.

И, кстати, я также обнаружил еще одну ошибку механизации, при которой <textarea>, содержащийся в <p>, не распознается как действительный элемент управления, но как только вы вытащите его из контейнера <p>, он распознается просто отлично , И я проверил, текстовая область разрешена для включения в другие элементы уровня блока, такие как <p>.

7 голосов
/ 09 апреля 2009

Я бы посоветовал вам использовать Twill, который использует mechanize (в основном это monkeypatched). Допустим, у вас есть форма с некоторыми полями и две кнопки отправки с именами"submit_to_preview" и "real_submit". Следующий код должен работать.

Кстати, помните, что это не потокобезопасно, поэтому вы можете использовать блокировки в случае, если вы хотите использовать код в многопоточном окружении.

import twill.commands
b = twill.get_browser()
url = "http://site/myform"
twill.commands.go(url)
twill.commands.fv("2", "name", "Me")
twill.commands.fv("2", "age", "32")
twill.commands.fv("2", "comment", "useful article")
twill.commands.browser.submit("real_submit")

Надеюсь, это поможет. Приветствия.

4 голосов
/ 12 августа 2009

Используйте метод click. Э.Г.

mybrowser.select_form(nr=0)
req = mybrowser.click(type="submit", nr=1)
mybrowser.open(req)

Должно работать.

2 голосов
/ 09 апреля 2009

Я могу говорить из опыта использования HTTP, а не механизации, но я думаю, что это, вероятно, то, что вы хотите.

Когда в форме есть две кнопки отправки, сервер может определить, какая из них была нажата, потому что клиент должен был добавить аргумент для кнопки отправки. Итак:

<form action="blah" method="get">
    <p>
        <input type="submit" name="button_1" value="One" />
        <input type="submit" name="button_2" value="Two" />
    </p>
</form>

Примет вас либо URL:

blah?button_1=One

или

blah?button_2=Two

В зависимости от того, какая кнопка была нажата.

Если вы программно определяете, какие аргументы будут отправлены, вам нужно добавить аргумент с названием нажатой кнопки отправки и ее значением.

...