Заполнение странной веб-формы в Python

0

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

Я бы дал конкретный пример того, что я пытаюсь сделать, и, надеюсь, он прояснит ситуацию:

  1. Допустим, я хочу, чтобы автоматический скрипт получил цену за гостиницу, веб-сайт был бы: веб-сайт Hilton

  2. На этой веб-странице я хочу заполнить запрос следующим образом: "где вы собираетесь" должен иметь NYC и дату отправления и прибытия.

  3. Если вы используете браузер, я получу следующую страницу с результатами для запроса, который я только что заполнил, и с этой веб-страницы я хочу очистить цены.

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

Ну, вот как я думал это сделать (очень общее описание....)

import urllib
import urllib.request

url = 'http://www3.hilton.com/en/index.html'
query_args = { 'searchQuery':' New York, NY ', 'arrivalDate':'31 Oct 2013' ,                         'departureDate': '04 Nov 2013' }
print (query_args)
data = urllib.parse.urlencode(query_args)
print (data)
request = urllib.request.Request(url);
response = urllib.request.urlopen(request,data)
html = response.read()
print (html)
  1. Прежде всего, я получаю следующую ошибку при отправке запроса: "TypeError: POST-данные должны быть байтами или итерабельными байтами. Это не может быть типа str". кто знает почему?

  2. Если бы я понял, я бы согласился с ответом на следующий веб-сайт. hilton_website с сегментом urlencode в конце (searchQuery = + New + York% 2C + NY & arrivalDate = 31 + Oct + 2013 & departureDate = 04 + ноябрь + 2013)

Но нет такого веб-сайта (когда я набираю полный адрес URL-адреса браузера), он выглядит как все результаты (и неважно, каков был ваш запрос или как вы заполнили форму), на той же веб-странице: hilton_web_site... en_US/привет/поиск /findhotels/Results.htm? вид = LIST

Так что я делаю неправильно? Я думал, что это способ заполнить веб-форму.

Большое спасибо за помощь

  • 0
    Правило № 1: отправьте все данные формы в вашем запросе (даже если они пустые), иначе сервер будет вас ненавидеть. Правило № 2: Вы уверены, что данные отформатированы правильно? (Текст, представленный, скажем, в раскрывающемся списке, не обязательно является ЗНАЧЕНИЕМ , отправляемым на сервер. Если вы используете Google Chrome, Меню -> Инструменты -> Инструменты разработчика -> (вкладка) Сеть -> нажмите кнопку Hilton файл страницы, на который вы отправляете запрос поиска. Теперь на нем должно появиться «Запросить заголовки», а справа небольшой текст с надписью «Показать исходный код», нажмите его и просмотрите, что вы на самом деле отправляете на сервер.)
  • 0
    Можете ли вы объяснить, как это возможно, что 2 разных Quaireis имеют один и тот же запрос?
Показать ещё 2 комментария
Теги:

1 ответ

0
Лучший ответ

Здесь дамп формы поиска hiltons (который, я инструктировал вас, как получить, но не могу вставить все это в раздел комментариев, так что здесь вы идете), я забыл упомянуть, что вы должны проверить "данные данных формы" в Chrome tho который был моим плохим.. во всяком случае..

RAW (чтобы вы могли понять, как работает POST-запрос)

Заголовок запроса

POST /en_US/hi/search/findhotels/index.htm?WT.bid=Home,,,find_button HTTP/1.1
Host: www3.hilton.com
Connection: keep-alive
Content-Length: 475
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Origin: http://www3.hilton.com
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Referer: http://www3.hilton.com/en/index.html
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Cookie: mmcore.tst=0.626; ClrCSTO=T; ClrSSID=1382526492268-11812; ClrOSSID=1382526492268-11812; ClrSCD=1382526492268; mmid=-1914085652%7CAQAAAAq0Q+DZtwkAAA%3D%3D; mmcore.pd=-1914085652%7CAQAAAAq0Q+DZtwkAAA%3D%3D; mmcore.srv=ldnvwcgus01; K3R7=3U24QMiCUbjeh65LoEI31TTjisY8czr4zkIUe06gsA4A5lc0bIKrEhQ; GWSESSIONID=qYDpSnSLNFnJ5CrJrwlSWW7CNBHL7vXSMndGmnxghGns1rLjt2lX!-1490734837; __atuvc=1%7C43; mm_pc_HHonorsPoints=false; mm_pers_storage=loggedin%3Ano%7CStayDuration%3A1-2%20nights%7CDaysToBooking%3A0-1%7CSatStay%3Ano%7CChildren%3Ano%7CBrand%3Ahi%7CHHonorsPoints%3Afalse%7CFlexDates%3Afalse%7CPromoCode%3Ano%7Cproperties8%3Ano%7Chotelcode%3Ano; WT_FPC=id=6f7c5181-8354-430b-b943-9bb95bf2c75c:lv=1382490515002:ss=1382490495203

Данные формы

searchQuery=N.Y.C&arrivalDate=23+Oct+2013&departureDate=24+Oct+2013&_flexibleDates=on&numberOfRooms=1&numberOfAdults%5B0%5D=1&numberOfChildren%5B0%5D=0&numberOfAdults%5B1%5D=1&numberOfChildren%5B1%5D=0&numberOfAdults%5B2%5D=1&numberOfChildren%5B2%5D=0&numberOfAdults%5B3%5D=1&numberOfChildren%5B3%5D=0&promoCode=&groupCode=&corporateId=&_travelAgentRate=on&_aaaRate=on&_aarpRate=on&_seniorRate=on&_governmentRate=on&offerId=&bookButton=false&searchType=ALL&roomKeyEnable=true

И это ключи (а не значения), которые вам нужно отправить с каждым поисковым запросом:

  • поисковый запрос
  • Дата прибытия
  • Дата отбытия
  • _flexibleDates
  • количество комнат
  • numberOfAdults% 5B0% 5D
  • numberOfChildren% 5B0% 5D
  • numberOfAdults% 5B1% 5D
  • numberOfChildren% 5B1% 5D
  • numberOfAdults% 5В2% 5D
  • numberOfChildren% 5В2% 5D
  • numberOfAdults% 5B3% 5D
  • numberOfChildren% 5B3% 5D
  • промо код
  • код группы
  • Пропуск
  • _travelAgentRate
  • _aaaRate
  • _aarpRate
  • _seniorRate
  • _governmentRate
  • offerId
  • bookButton
  • SearchType
  • roomKeyEnable

И вот что такое построение python всей вещи будет выглядеть так:

from socket import *
s = socket()

POST = 'searchQuery=N.Y.C&arrivalDate=23+Oct+2013&departureDate=......'

header = ''
header += 'POST /en_US/hi/search/findhotels/index.htm?WT.bid=Home,,,find_button HTTP/1.1\r\n'
header += 'Host: www3.hilton.com\r\n'
header += 'Connection: keep-alive\r\n'
header += 'Content-Length: ' + str(len(POST)) + '\r\n'
header += 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n'
header += 'Origin: http://www3.hilton.com\r\n'
header += 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) \r\n'
header += 'Chrome/30.0.1599.101 Safari/537.36\r\n'
header += 'Content-Type: application/x-www-form-urlencoded\r\n'
header += 'Referer: http://www3.hilton.com/en/index.html\r\n'
header += 'Accept-Encoding: gzip,deflate,sdch\r\n'
header += 'Accept-Language: en-US,en;q=0.8\r\n'
header += '\r\n'

s.connect(('www3.hilton.com', 80))
s.send(header+POST)
print(s.recv(8192))

И это даст вам то, что вы ищете. Обратите внимание, что я не использовал поле cookie в заголовке. Обычно сервер не заботится о нем, потому что это древняя техника и там для сервера обычно подразумевается, что если куки не были предоставлены, просто дайте клиенту новые и предположим, что это первое посещение даже tho (хорошо технически это так), это действительно не первая первая страница.

Также обратите внимание:

Все данные в переменной POST должны быть закодированы как URL: urlencode(key)=urlencode(val)& для каждой пары. Обратите внимание, как я не кодировал url = или & в этом необработанных POST-данных.

Здесь вам не нужно беспокоиться об этом, потому что urllib делает это за вас. Но это дает вам представление о том, как работают HTTP-запросы.

  • 0
    так что функция, которую я использовал "urlopen" в приведенном выше сценарии (с полными параметрами queary), не достаточно? это можно сделать только с помощью этой функции?
  • 0
    @ user2910088 Это можно сделать с помощью urlopen , вам просто нужно добавить больше параметров в ваши данные POST (точнее, все элементы в моем списке выше, даже если значения пусты)
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню