Я пытаюсь создать простую программу, которая заполняет веб-форму, а затем извлекает данные с приведенного веб-сайта, она должна быть довольно прямой и после коротких веб-исследований (в основном с этого веб-сайта) я пришел к выводу, что python будет мой лучший выбор. (с urllib)
Я бы дал конкретный пример того, что я пытаюсь сделать, и, надеюсь, он прояснит ситуацию:
Допустим, я хочу, чтобы автоматический скрипт получил цену за гостиницу, веб-сайт был бы: веб-сайт Hilton
На этой веб-странице я хочу заполнить запрос следующим образом: "где вы собираетесь" должен иметь NYC и дату отправления и прибытия.
Если вы используете браузер, я получу следующую страницу с результатами для запроса, который я только что заполнил, и с этой веб-страницы я хочу очистить цены.
Предположим, что очистка данных может быть выполнена из исходного кода 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)
Прежде всего, я получаю следующую ошибку при отправке запроса: "TypeError: POST-данные должны быть байтами или итерабельными байтами. Это не может быть типа str". кто знает почему?
Если бы я понял, я бы согласился с ответом на следующий веб-сайт. 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
Так что я делаю неправильно? Я думал, что это способ заполнить веб-форму.
Большое спасибо за помощь
Здесь дамп формы поиска 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
И это ключи (а не значения), которые вам нужно отправить с каждым поисковым запросом:
И вот что такое построение 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-запросы.
urlopen
, вам просто нужно добавить больше параметров в ваши данные POST (точнее, все элементы в моем списке выше, даже если значения пусты)