Python chanize — две кнопки типа «отправить»

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


person directedition    schedule 09.04.2009    source источник


Ответы (4)


Я попытался использовать параметр 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 /> ... и, что еще менее логично, у меня не могло быть ничего между двумя кнопками отправки.

Меня бесконечно расстраивало, что ошибка chanize/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>

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

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

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

person Chirael    schedule 06.11.2009

Я бы посоветовал вам использовать Twill, который использует механизацию (в основном с обезьяньим патчем). Допустим, у вас есть форма с несколькими полями и двумя кнопками отправки с именами "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")

Надеюсь, это поможет. Ваше здоровье.

person Shekhar    schedule 09.04.2009

Используйте метод «щелчок». Например.

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

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

person Kyle    schedule 11.08.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

or:

blah?button_2=Two

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

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

person SpoonMeiser    schedule 09.04.2009