воскресенье, 10 июня 2012 г.

Python 101: Как отправить форму (Перевод)


Сегодня мы потратим немного времени, рассматривая три разных способа отправки веб-формы. В нашем случае мы поищем на duckduckgo.com слово "python" и сохраним результат в HTML файле. Мы будем использовать встроенный модуль urllib и два модуля от сторонних производителей: requests и mechanize. В итоге мы получим три маленьких скрипта. Приступим!

Отправка формы с помощью urllib

Мы начнём с urllib и urllib2, так как это встроенные модули. Мы так же импортируем webbrowser для открытия результата поиска. Вот сам код:

import urllib
import urllib2
import webbrowser

url = "http://duckduckgo.com/html"
data = urllib.urlencode({'q': 'Python'})
results = urllib2.urlopen(url, data)
with open("results.html", "w") as f:
    f.write(results.read())

webbrowser.open("results.html")


Первое, что Вам надо сделать если Вы хотите отправить форму - это понять, какой адрес использовать. Если Вы откроете выбранный нами поисковик и посмотрите код страницы, Вы увидите, что действие привязано к относительной ссылке, “/html”. Так что наш url это “http://duckduckgo.com/html”. Поле запроса названо “q”, так что передавая запрос поисковику мы передаём поле “q”. Вот тут нам и нужен urllib.urlencode. Он правильно закодирует наш поисковый запрос, после чего мы открываем нужный нам url и ждём, пока выполнится поиск. Результат считываем и сохраняем на диск. И, наконец, мы открываем сохранённый результат используя модуль webbrowser.

Отправка формы при помощи requests

Модуль requests позволяет нам сделать это немного элегантнее:

import requests

url = "http://duckduckgo.com/html"
payload = {'q':'python'}
r = requests.post(url, payload)
with open("requests_results.html", "w") as f:
    f.write(r.content)

Для requests Вам надо создать словарь с именем поля в качестве ключа и поисковым запросом в качестве значения. Затем Вы используете requests.post для выполнения поиска. И, наконец, Вы получаете объект с результатом, "r", считываете значение его свойства content и сохраняете результат на диск. (открытие файла мы тут не показали, так как оно ни чем  не отличается от предыдущего случая)

Отправка формы при помощи mechanize

Модуль mechanize содержит много прикольных возможностей для работы с интернетом посредством Python. К сожалению, он не поддерживает javascript. В любом случае, посмотрим, что получится:

import mechanize

url = "http://duckduckgo.com/html"
br = mechanize.Browser()
br.set_handle_robots(False) # ignore robots
br.open(url)
br.select_form(name="x")
br["q"] = "python"
res = br.submit()
content = res.read()
with open("mechanize_results.html", "w") as f:
    f.write(content)

Как можно видеть, mechanize требует чуть больше кода, чем два других метода. Кроме того, мы должны явно указать ему, что надо игнорировать robots.txt или мы получим ошибку. Конечно, если Вы хотите быть хорошим "гражданином сети", Вам не стоит этого делать. В любом случае, для начала Вам нужен объект Browser. Затем Вы открываете url, выбираете форму (в нашем случае "x") и заполняете словарь, который содержит параметры поиска, как в предыдущих случаях. Обратите внимание, что в каждом случае заполнение словаря происходит немного по другому. После этого Вы отправляете запрос и считываете результат, который сохраняете на диск.

Итого

Из всех трёх, метод requests наиболее простой, за ним вплотную идёт urllib. Mechanize сделан для более широких целей - тестирования сайтов и выделения данных из отображаемой на экране информации (screen scraping), поэтому не удивительно, что он более многословен. Кроме того, вы можете использовать selenium, но об этом Вы можете почитать в архиве. Надеюсь, это было интересно и увлекающе. До встреч!

Что почитать? Screen Scraping sample chapter
Исходники form_submission.zip

Источник

3 комментария:

  1. Ошибка! (у меня последний requests)
    f.write(r.content)
    TypeError: must be str, not bytes

    ОтветитьУдалить
    Ответы
    1. Какая версия питона? Вторая?
      Попробуйте

      open("requests_results.html", "wb") as f:

      Удалить