Подтвердить что ты не робот

Как отправить запрос на страницу .aspx в python

Мне нужно очистить результаты запроса с веб-страницы .aspx.

http://legistar.council.nyc.gov/Legislation.aspx

URL-адрес статичен, поэтому как отправить запрос на эту страницу и получить результаты? Предположим, нам нужно выбрать "все годы" и "все типы" из соответствующих выпадающих меню.

Кто-то должен знать, как это сделать.

4b9b3361

Ответ 1

В качестве обзора вам необходимо выполнить четыре основные задачи:

  • чтобы отправить запрос на веб-сайт,
  • для получения ответа (ответов) с сайта
  • для анализа этих ответов
  • иметь некоторую логику для повторения в вышеперечисленных задачах с параметрами, связанными с навигацией (на "следующие" страницы в списке результатов)

Обработка запросов HTTP и ответов выполняется с помощью методов и классов из стандартной библиотеки Python urllib и urllib2. Разбор html-страниц можно выполнить с помощью стандартной библиотеки Python HTMLParser или с другими модулями, такими как Красивый суп

Следующий фрагмент демонстрирует запрос и получение поиска на сайте, указанном в вопросе. Этот сайт ориентирован на ASP, и в результате мы должны обеспечить отправку нескольких полей формы, некоторые из которых имеют "ужасные" значения, поскольку они используются логикой ASP для поддержания состояния и для аутентификации запроса в некоторой степени. Действительно, отправляю. Запросы должны быть отправлены с помощью метода http POST, поскольку это то, что ожидается от этого приложения ASP. Основная трудность заключается в определении поля формы и связанных значений, которые ASP ожидает (получение страниц с Python является легкой частью).

Этот код является функциональным или, точнее, функциональным, пока я не удалю большую часть значения VSTATE и, возможно, внедрил опечатку или два, добавив комментарии.

import urllib
import urllib2

uri = 'http://legistar.council.nyc.gov/Legislation.aspx'

#the http headers are useful to simulate a particular browser (some sites deny
#access to non-browsers (bots, etc.)
#also needed to pass the content type. 
headers = {
    'HTTP_USER_AGENT': 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.13) Gecko/2009073022 Firefox/3.0.13',
    'HTTP_ACCEPT': 'text/html,application/xhtml+xml,application/xml; q=0.9,*/*; q=0.8',
    'Content-Type': 'application/x-www-form-urlencoded'
}

# we group the form fields and their values in a list (any
# iterable, actually) of name-value tuples.  This helps
# with clarity and also makes it easy to later encoding of them.

formFields = (
   # the viewstate is actualy 800+ characters in length! I truncated it
   # for this sample code.  It can be lifted from the first page
   # obtained from the site.  It may be ok to hardcode this value, or
   # it may have to be refreshed each time / each day, by essentially
   # running an extra page request and parse, for this specific value.
   (r'__VSTATE', r'7TzretNIlrZiKb7EOB3AQE ... ...2qd6g5xD8CGXm5EftXtNPt+H8B'),

   # following are more of these ASP form fields
   (r'__VIEWSTATE', r''),
   (r'__EVENTVALIDATION', r'/wEWDwL+raDpAgKnpt8nAs3q+pQOAs3q/pQOAs3qgpUOAs3qhpUOAoPE36ANAve684YCAoOs79EIAoOs89EIAoOs99EIAoOs39EIAoOs49EIAoOs09EIAoSs99EI6IQ74SEV9n4XbtWm1rEbB6Ic3/M='),
   (r'ctl00_RadScriptManager1_HiddenField', ''), 
   (r'ctl00_tabTop_ClientState', ''), 
   (r'ctl00_ContentPlaceHolder1_menuMain_ClientState', ''),
   (r'ctl00_ContentPlaceHolder1_gridMain_ClientState', ''),

   #but then we come to fields of interest: the search
   #criteria the collections to search from etc.
                                                       # Check boxes  
   (r'ctl00$ContentPlaceHolder1$chkOptions$0', 'on'),  # file number
   (r'ctl00$ContentPlaceHolder1$chkOptions$1', 'on'),  # Legislative text
   (r'ctl00$ContentPlaceHolder1$chkOptions$2', 'on'),  # attachement
                                                       # etc. (not all listed)
   (r'ctl00$ContentPlaceHolder1$txtSearch', 'york'),   # Search text
   (r'ctl00$ContentPlaceHolder1$lstYears', 'All Years'),  # Years to include
   (r'ctl00$ContentPlaceHolder1$lstTypeBasic', 'All Types'),  #types to include
   (r'ctl00$ContentPlaceHolder1$btnSearch', 'Search Legislation')  # Search button itself
)

# these have to be encoded    
encodedFields = urllib.urlencode(formFields)

req = urllib2.Request(uri, encodedFields, headers)
f= urllib2.urlopen(req)     #that the actual call to the http site.

# *** here would normally be the in-memory parsing of f 
#     contents, but instead I store this to file
#     this is useful during design, allowing to have a
#     sample of what is to be parsed in a text editor, for analysis.

try:
  fout = open('tmp.htm', 'w')
except:
  print('Could not open output file\n')

fout.writelines(f.readlines())
fout.close()

Это о том, чтобы получить начальную страницу. Как было сказано выше, нужно было бы проанализировать страницу, т.е. Найти интересующие ее части и собрать их по мере необходимости и сохранить их в файле/базе данных/везде. Эта работа может быть выполнена очень многими способами: с использованием синтаксических анализаторов html или типов технологий XSLT (действительно, после разбора html на xml) или даже на грубые задания - простое регулярное выражение. Кроме того, одним из элементов, которые обычно извлекаются, является "следующая информация", то есть ссылка рода, которая может быть использована в новом запросе на сервер для получения последующих страниц.

Это должно дать вам грубый аромат того, что такое "длинная рука" html scraping. Есть много других подходов к этому, таких как посвященные utilties, скрипты в Mozilla (FireFox) подключаемый модуль GreaseMonkey, XSLT...

Ответ 2

Selenium - отличный инструмент для использования в этой задаче. Вы можете указать значения форм, которые вы хотите ввести, и получить html страницы ответа в виде строки в нескольких строках кода python. Используя Selenium, вам, возможно, не придется выполнять ручную работу по моделированию действительного почтового запроса и всех его скрытых переменных, как я узнал после многих проб и ошибок.

Ответ 3

Большинство сайтов ASP.NET(на которые вы ссылались включены) будут отправлять свои запросы обратно сами по себе, используя HTTP POST-глагол, а не GET-глагол. Вот почему URL-адрес не изменяется, как вы отметили.

Что вам нужно сделать, это посмотреть на сгенерированный HTML и зафиксировать все их значения форм. Обязательно запишите все значения формы, так как некоторые из них используются для проверки страницы, и без них ваш запрос POST будет отклонен.

Помимо проверки, страница ASPX в отношении очистки и публикации не отличается от других веб-технологий.

Ответ 4

Код в других ответах был полезен; Я никогда бы не смог написать свой сканер без него.

Одна проблема, с которой я столкнулся, - это файлы cookie. Сайт, который я просматривал, использовал файлы cookie для записи идентификатора сеанса/безопасности, поэтому мне пришлось добавить код, чтобы заставить мой искатель работать:

Добавьте этот импорт:

    import cookielib            

Инициируйте файлы cookie:

    COOKIEFILE = 'cookies.lwp'          # the path and filename that you want to use to save your cookies in
    cj = cookielib.LWPCookieJar()       # This is a subclass of FileCookieJar that has useful load and save methods

Установите CookieJar, чтобы он использовался как стандартный CookieProcessor в обработчике дескриптора по умолчанию:

    cj.load(COOKIEFILE)
    opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
    urllib2.install_opener(opener)

Чтобы узнать, какие файлы cookie использует сайт:

    print 'These are the cookies we have received so far :'

    for index, cookie in enumerate(cj):
        print index, '  :  ', cookie        

Это сохраняет файлы cookie:

    cj.save(COOKIEFILE)                     # save the cookies 

Ответ 5

"Предположим, нам нужно выбрать" все годы "и" все типы "из соответствующих выпадающих меню.

Что делают эти параметры для URL, который в конечном итоге представлен.

В конце концов, он равен HTTP-запросу, отправленному через urllib2.

Знаете, как делать "все годы" и "все типы" из соответствующих выпадающих меню, вы делаете следующее.

  • Выберите "Все годы" и "все типы" из соответствующих выпадающих меню

  • Обратите внимание на URL, который фактически отправлен.

  • Используйте этот URL-адрес в urllib2.