Помогите разобраться - как извлечь информацию со страницы?
Вот такое классическое "найди то, не знаю что".Перебирать на поисковиках типа skyscanner или momodo все даты - это я состарюсь раньше, чем закончу. В связи с этим возникла идея автоматизировать процесс - не зря же я учила питон.как именно? какие данные ты хочешь получить и что они тебе дадут в плане выбора путешествия?
пс. питона в топку. юзай грисманки
Особо не разбирался, но, судя по тому, как у них там всё наворочено, лично я бы на их месте тебе даже адресов скриптов своих просто так не показал, чтоб знать хотя бы, куда эти аяксы ломятся ))
Ну можно, конечно, проследить, кто и куда ломится, но там тоже наверняка стоит защита по кукам или сессиям
Так что грейсманки, да...
Я хотела бы следующее:
- как минимум - пробежать по всем датам и всем интересующим меня направлениям и выгрузить минимальные цены в файлик, чтобы потом просто посмотреть файлик и понять, в каком месяце и куда стоит лететь.
- как максимум - выгрузить не только самый дешевый, но по паре других удобных для меня рейсов (например, не больше одной пересадки и переседка не дольше 3-4 часов). Чтобы потом в спокойной обстановке это изучить.
Ну вот чтоб в файлик - точно надо разбираться, куда оно какие запросы шлёт, что в этих запросах передаёт браузер, что от этих запросов ожидает бекенд.. А потом уже их же и отправлять скриптом через тот же cURL, к примеру.
Питон не поможет, правда - нужно минимальное знание js.
А вообще не надо блондиностью прикрываться - задачка-то совсем не тривиальная
Ну вот чтоб в файлик - точно надо разбираться, куда оно какие запросы шлёт, что в этих запросах передаёт браузер, что от этих запросов ожидает бекенд.. А потом уже их же и отправлять скриптом через тот же cURL, к примеру.Вот это самое правильное - открой сайт в хроме, включи developer tools, посмотри какие запросы шлются. Скорее всего там есть нормальное rest api
http://selenium-python.readthedocs.org/
этот сайт не отдаёт тебе данные. Он отдаёт приложение, написанное на javascript, которое уже впоследствии занимается отрисовкой и обменом. Ты не можешь его распарсить, ты должна его запустить. Для запуска веб приложений в искусственном окружении используется selenium. Он позволяет получить финальный вывод программы после её отработки.
подразумевается, что тебя ждёт левел-ап: этот сайт не отдаёт тебе данные. Он отдаёт приложение, написанное на javascript, которое уже впоследствии занимается отрисовкой и обменом. Ты не можешь его распарсить, ты должна его запустить. Для запуска веб приложений в искусственном окружении используется selenium. Он позволяет получить финальный вывод программы после её отработки.
Какие запросы шлет - уже смотрела, их там туева хуча. Он же проходится по многим агентствам по продаже билетов и сайтам авиакомпаний.
Посмотрела js файлы, которые есть на momondo.ru и momondo.net - этой переменной там нет. Видимо, специально прячут от таких, как я.
Федя, я ж думала, там все просто! А оказалось непросто...
Посмотрела js файлы, которые есть на momondo.ru и momondo.net - этой переменной там нет. Видимо, специально прячут от таких, как я.Ну вот даже собсно строки "flightRenderer" не видать в открытом тексте.
Есть, правда, кусок кода
<script type="text/javascript">_MomondoTripType='';_MomondoFlightSearchUrl='/multicity/';_DefaultResultView=0;_DefaultOverview='';_FlightRedirectBehavior=3</script>
Вполне возможно, что как раз по этому "/multicity/' еще кусок JS и отдается. Ну или еще примерно в таких местах. В общем, интересно, но лично мне разбираться точно лень ))
2 l0st: я знаю про этот функционал, но мне показалось, что он не особо точен. Самый интерес представляют вещи типа ошибок авиакомпаний (типа - добавь третий сегмент и получи три билета по цене в два раза ниже, чем за два). В идеале написать бы поисковик для таких штук. Тут скайсканнер не поможет - он не умеет искать составные маршруты.
Хотя для решения конкретно моей практической задачи твое предложение, пожалуй, самое быстро реализуемое.
Ну и когда я попыталась забрать данные с momondo скриптом, мне уже стало интересно, как это сделать.
Скорее всего там есть нормальное rest apiПоверхностным поиском не выявлено.
Может, быстрее у них спросить? И если он есть, то и воспользоваться?
http://awd.momondo.ru/api/3.0/FlightSearch
и получает в json идентификатор скролла (параметр SearchId):
{
"Segments" : [{
"Origin" : {
"Aliases" : null,
"ContinentCode" : null,
"ContinentGroup" : 0,
"CountryCode" : "RU",
"CountryName" : "Россия",
"DST" : null,
"DisplayName" : "Москва (MOW), Россия",
"Iata" : "MOW",
"IataLink" : false,
"Icao" : null,
"Latitude" : 55.7557869,
"Longitude" : 37.6176338,
"MainCityCode" : "MOW",
"MainCityDisplayName" : "Москва (MOW), Россия",
"MainCityName" : "Москва",
"Name" : "Москва",
"Priority" : 483,
"StateCode" : "",
"StateName" : "",
"TimeZone" : 0
},
"Destination" : {
"Aliases" : null,
"ContinentCode" : null,
"ContinentGroup" : 0,
"CountryCode" : "FI",
"CountryName" : "Финляндия",
"DST" : null,
"DisplayName" : "Хельсинки (L), Финляндия",
"Iata" : "L",
"IataLink" : false,
"Icao" : null,
"Latitude" : 60.31938,
"Longitude" : 24.9412041,
"MainCityCode" : "L",
"MainCityDisplayName" : "Хельсинки (L), Финляндия",
"MainCityName" : "Хельсинки",
"Name" : "Хельсинки-Вантаа",
"Priority" : 178,
"StateCode" : "",
"StateName" : "",
"TimeZone" : 0
},
"Departure" : "2016-01-15T00:00:00"
}
],
"SearchId" : "880a08fe-655e-45ec-8aad-801f160bf379",
"EngineId" : 8,
"AdultCount" : 1,
"ChildCount" : 0,
"InfantCount" : 0,
"ChildAges" : [],
"TicketClass" : "ECO",
"Culture" : "ru-RU"
}
После этого порциями по этому url:
http://awd.momondo.ru/api/3.0/FlightSearch/880a08fe-655e-45ec-8aad-801f160bf379/8/true
получает результаты поиска:
{
"SearchId" : "880a08fe-655e-45ec-8aad-801f160bf379",
"EngineId" : 8,
"Done" : false,
"Error" : false,
"ErrorMessage" : null,
"ResultNumber" : 1,
"Summary" : {
"BestOfferIndex" : 366,
"BestOfferSupplierIndex" : 17,
"CheapestOfferIndex" : 411,
"CheapestOfferSupplierIndex" : 19,
"FastestOfferIndex" : 366,
"FastestOfferSupplierIndex" : 17,
"Mauration" : 1730,
"MaxPrice" : 3835.73,
"MaxScore" : 2607.86,
"MinDuration" : 100,
"MinPrice" : 80.58,
"MinScore" : 129.9
},
"Airports" : [...],
"Airlines" : null,
"Fees" : [...],
"Flights" : [...],
"Legs" : [...],
"MixOffers" : null,
"Offers" : [{
"AdultPrice" : 0.0,
"AdultPriceEUR" : 0.0,
"AdultPriceExclTax" : 0.0,
"Currency" : "RUB",
"Deeplink" : "http://avia.tickets.ru/preloader?StartAirp1Code=MOW&EndAirp1Code=L&Date1=15-01-2016&adt=1&chd=0&inf=0&refid=72&class=E&r_hash=d3e60c91e3eaa5bdc0330ca9e3fb0482_PS576|PS151|:*43b9d43&act=book",
"FeeIndexes" : [16, 18, 24, 25, 26],
"FlightIndex" : 7,
"MobileDeepLink" : null,
"Score" : 302.79,
"TicketClassIndex" : 3,
"TotalIsCalculated" : false,
"TotalPrice" : 4983.00,
"TotalPriceEUR" : 80.58,
"TotalPriceExclTax" : 0.0
},
...
],
"TicketClasses" : [{
"Code" : "ECO",
"Name" : "economic_discounted"
}
]
}
Объединяет порции в один массив, сортирует по цене и отображает.
http://awd.momondo.ru/api/3.0/FlightSearchРаскопал ))
Блин, для меня пока что такое - за гранью не то что способностей, а даже понимания. В жизни не нашла бы.
Последнюю порцию можно идентифицировать по
"Done" : true,
1) я пишу запрос на http://awd.momondo.ru/api/3.0/FlightSearch , в качестве HTTP referer передаю ту строку, которая была в моем первом посте
2) скачиваю файл FlightSearch.json и вытаскиваю из него SearchId
3) подставляю его в http://awd.momondo.ru/api/3.0/FlightSearch/
4) отправляю запрос на получившийся url до тех пор, пока в ответ не получу файл с содержимым null
5) Ну дальше вроде все просто.
UPD: не файл с null, а Done = true
2) скачиваю файл FlightSearch.json и вытаскиваю из него SearchIdТы не скачиваешь файл, ты получаешь строку с текстом, в котором лежит JSON
4) отправляю запрос на получившийся url до тех пор, пока в ответ не получу ...JSON c Done=true
Спасибо!
Удаачи в танцах с бубном.
4) отправляю запрос на получившийся url до тех пор, пока в ответ не получу JSON c Done=trueЕсли SearchID - это ID сессии (логичЬно), то "до тех пор" может быть ограничен временем сессии
Если SearchID - это ID сессии (логичЬно), то "до тех пор" может быть ограничен временем сессииНет, Федя, SearchID - это ID курсора по результатам выдачи поискового запроса. Куки/сессии тут не при чем вообще.
http://ru.wikipedia.org/wiki/%D0%9A%D1%83%D1%80%D1%81%D0%BE...
или вот:
http://www.elastic.co/guide/en/elasticsearch/reference/curr...
Например:Ага, ознакомился. Хотя, в общем-то, по тому, для чего нужны - те же сессии
P.S. Не, я на них не дрочу, просто так получилось
Я хотела бы следующее: - как минимум - пробежать по всем датам и всем интересующим меня направлениям и выгрузить минимальные цены в файлик, чтобы потом просто посмотреть файлик и понять, в каком месяце и куда стоит лететь. - как максимум - выгрузить не только самый дешевый, но по паре других удобных для меня рейсов (например, не больше одной пересадки и переседка не дольше 3-4 часов). Чтобы потом в спокойной обстановке это изучить.скайсканер или авиасейлс разве неумеют это из коробки?
Достаточно при выборе даты выбрать "Весь месяц", а в поле куда выбрать "Везде", дальше даст возможность выбрать страну и дату с самыми дешевыми билетами =)
Код:
import requests
search_url = 'http://awd.momondo.ru/flightsearch/?' + \
'Search=true&TripType=1&SegNo=1&SO0=MOW&SD0=L&' + \
'SDP0=15-01-2016&AD=1&TK=ECO&DO=false&NA=false#Search=true' + \
'&TripType=1&SegNo=1&SO0=MOW&SD0=L&SDP0=15-01-2016&AD=1&' + \
'TK=ECO&DO=false&NA=false'
mom_url = 'http://awd.momondo.ru/api/3.0/FlightSearch'
search_headers = {'Referer':search_url}
search_result = requests.get(mom_url, headers = search_headers)
print (search_result.json()) # Для начала пытаюсь просто напечатать json
В ответ радостно получаю "Ready". И все.
Если добавляю "http.client.HTTPConnection.debuglevel = 1", вижу вот что:
send: b'GET /api/3.0/FlightSearch HTTP/1.1\r\nHost: awd.momondo.ru\r\nUser-Agent: python-requests/2.7.0 CPython/3.4.3 Windows/8\r\nAccept-Encoding: gzip, deflate\r\nConnection: keep-alive\r\nReferer: http://awd.momondo.ru/flightsearch/?Search=true&TripType... */*\r\n\r\n'
reply: 'HTTP/1.1 200 OK\r\n'
header: Via header: Connection header: Proxy-Connection header: Content-Length header: Expires header: Date header: Content-Type header: Server header: Cache-Control header: Pragma header: Set-Cookie header: Set-Cookie header: Set-Cookie header: X-AspNet-Version header: Set-Cookie
Мой Referer передался, но, видимо, сервер его не принял, так что ли? Потому что почему иначе он не передал json? Или, может, ему нужны еще какие-то заголовки? Может, он user-agent видит и злорадно меня посылает?
import urllib2
import json
search_request = {"AdultCount":1,
"ChildAges":[],
"TicketClass":"ECO",
"Segments":[{"Origin":"MOW","Destination":"L","Depart":"2016-01-15T17:00:00.000Z","Departure":"2016-01-15"}],
"Culture":"ru-RU",
"Mix":"None",
"Market":"",
"DirectOnly":False,
"IncludeNearby":True
}
req = urllib2.Request(
url = 'http://awd.momondo.ru/api/3.0/FlightSearch',
data = json.dumps(search_request),
headers = {'Content-Type': 'application/json'}
)
f = urllib2.urlopen(req)
search_object = json.loads(f.read())
search_id = search_object['SearchId']
engine_id = search_object['EngineId']
search_url = "http://awd.momondo.ru/api/3.0/FlightSearch/%s/%s/true" % (search_id, engine_id)
print "Opening", search_url
f = urllib2.urlopen(search_url)
print f.read()
Ой, я не пролистал до тела запроса.
http://business.skyscanner.net/portal/en-GB/Documentation/Fl...
http://support.travelpayouts.com/hc/ru/sections/200613133-%...
Возможно, как закончу - попробую и твой вариант.
Но я уже начала писать по момондо, у него апи нетВ смысле?
А Кротишка тебе что озвучил?
Но я уже начала писать по момондо, у него апи нет.а это что ?
search_url = "http://awd.momondo.ru/api/3.0/FlightSearch/%s/%s/true" % (search_id, engine_id)
Ну я предполагала, что апи поставляет разработчик, ну и вообще что это что-то официальное.
Расскажите, как вы смотрели, какие запросы шлет сайт - через Developer tools в браузере?
Подскажите ещё пожалуйста, как можно авторизоваться используя логин и пароль , для конкретики/примера - на forumlocal, также используя питон.
Подскажите ещё пожалуйста, как можно авторизоваться используя логин и пароль , для конкретики/примера - на forumlocal, также используя питон.Общий метод такой:
Берёшь браузер например хром или оперу, или ФФ, и нажимаешь на Ctrl+Shift+I
появляется панель разработчика, в ней переключаешься на вкладку "сеть"
затем в переходишь на страничку где вводишь логин пароль , вводишь их и смотришь , что появляется в логах сетевого взаимодействия.
Там будет запрос на адрес в теле которого в параметрах встретятся твои введенные логин и пароль, например test test
POST HTTP/1.1
Host: forumlocal.ru
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer:
Cookie: w3t_w3t_language=russian
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 136
Cat=&Loginname=test&Loginpass=test&ipbind=1&firstlogin=1&postdata_protection_key=119140b26e3dc99fdc08f2f&buttlogin=%C2%F5%EE%E4
ЗДесь в запросе еще есть параметр postdata_protection_key - надо будет проверить, влияет ли он на успешность залогинивания, если выяснится что он обязателен то сначала надо будет взять страницу входа и распарсить её, найдя в тексте значение postdata_protection_key , там будет что то вида <input type=hidden name=postdata_protection_key value=119140b26e3dc99fdc08f2f>
В ответ сервер пришлёт куки (и ответ и куки видны в той же панели), самая интересная w3t_w3t_mysess:"d19c688f208f45fa50" или аналогичная
её значение в последующем надо передавать во все запросы к форуму, например в запросе входящих приватов:
GET
Host: forumlocal.ru
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer:
Cookie: w3t_w3t_language=russian; w3t_w3t_myid=10419; w3t_w3t_mysess=d19c688f208f45fa50
Connection: keep-alive
сам код примерно такой же как у асета, только еще после запроса надо извлечь кукисы из ответа.
Headers рекомендую передавать такие какие передаёт обычный браузер, чтобы избежать палева бота.
спасибо!
Сообщение удалил
loginData.put("Loginname", login);
loginData.put("Loginpass", password);
loginData.put("rememberme", "1");
loginData.put("firstlogin", "1");
loginData.put("ipbind", "0");
loginData.put("postdata_protection_key", config.POST_PROTECTION_KEY);
loginData.put("buttlogin", "1");
>>> import requests
>>> import lxml.html
>>> url = "http://forumlocal.ru/login.php"
>>> session = requests.Session()
>>> s = session.get(url)
>>> doctree = lxml.html.document_fromstring(s.text)
>>> inputs = doctree.xpath('/html/body/table[4]/tr/td/table/tr[2]/td/form/input')
>>> for inp in inputs:
... print inp.name
...
Cat
Loginname
Loginpass
rememberme
ipbind
firstlogin
postdata_protection_key
buttlogin
buttlogin не передавал в форму. Потому логин не проходил. Возвращало "Не были заполнены все обязательные поля."
Re алсо: Чтобы со спириткой не путать.
В общем, еще раз всем спасибо, прощаюсь с вами ненадолго - скоро опять приду с вопросами.
Ну, ты нас тоже радуй, if you know, what i mean.
Ну, ты нас тоже радуй, if you know, what i mean.ты про фотку?
http://cornerapp.com, возможно, там уже есть все, что нужно.
Под эту задачу затачивался - получить с хабра все статьи из хаба python или с тегом python
- получить авторов этих статей и всех тех, кто их комментировал
- получить регион из профиля для каждого контакта
- отфильтровать тех, кто из Одессы
- написать каждому вопросы по статье
- получить с хабра все статьи из хаба python или с тегом pythonгы-гы. буквально на днях видел вакансию на стэковерфлоу в которой это было тестовым заданием. денег кстати не плохо предлагали.
Научите лучше девушку xpath или xslt.
Научите лучше девушку xpath или xslt.Лучше не учите девушку этому дерьму!
Ну серьезно, xslt это худший язык ever. Чтобы это понять, достаточно посмотреть на программу, которая возвращает тот же документ, который был передан ей на вход. Звучит просто, да?
А вот для краулеров всяких по-быстренькому скрипт разовый набросать - это можно.
Извини, я не понимаю разницы между словами "программа" и "скрипт".
Скрипт = программа, которую запускают один раз.
А если я его в крон пропишу, он станет "программой"?
В скрипте позволительно не обрабатывать исключения, ошибки ввода и вообще он может запускаться только в идеальных тепличных условиях под твоим надзором. Потом его надо выбросить.
Потому что быстрее и проще написать его заново, чем хранить всякую хрень.
Научите лучше девушку xpath или xslt.Xslt - мертвая технология. Xml сейчас не в моде.
Xpath полезная штука. Даже не он сам, а понимание его принципов. При разборе html-я, аналог xpath-а очень полезный подход для идентификации элементов.
ps
Интересно, а graphql в простых приложениях применим? Или он прибит гвоздями к большим проектам, бд и т.д.?
Xslt - мертвая технология.
ок, уговорил.
Xpath полезная штука.есть ещё всякие jsonpath и пр.
Интересно, а graphql в простых приложениях применим? Или он прибит гвоздями к большим проектам, бд и т.д.?Сейчас есть graphql reference implementation на js. Она позволяет описать типизированную схему, умеет парсить запросы и отвечать на запросы по интроспекции схемы. Бэкенда (то есть кода который получает откуда-то данные) никакого нет, можно реализовать свой простой бэкенд, например http://davidandsuzi.com/writing-a-basic-api-with-graphql/
Если ты интересуешься в контексте этой задачи
Следующее задание )то тебе graphql не особо помог бы. Он не позволяет делать adhoc запросы. Скорее всего, ты смог бы одним запросом зафетчить все, кроде последнего шага, а фильтровать по городу пришлось бы на клиенте
- получить с хабра все статьи из хаба python или с тегом python
- получить авторов этих статей и всех тех, кто их комментировал
- получить регион из профиля для каждого контакта
- отфильтровать тех, кто из Одессы
- написать каждому вопросы по статье
Он не позволяет делать adhoc запросы.Нафига он такой тогда нужен?
Xslt - мертвая технологияа что кстати есть на замену? ну например, надо пдфу, или док файл сгенерить. xslt/fo+xml для этого вроде неплохо подходят.
а что кстати есть на замену?любимый язык + xpath
xslt/fo+xml для этого вроде неплохо подходят.afaik, это единственный продукт, который более-менее использует xslt. имхо, ради одного этого продукта xslt использовать не стоит.
Кстати, точно. Все преобразования между разными форматами электронных книг через xslt идут.
Есть решения для каждой задачи по отдельности.
чем сейчас xslt лучше чем просто взять и написать хоть даже на php?
Ну а зачем в проект на яве или питоне вкорячивать (прости госсподи) пхп?
что там, нет библиотек чтоб сделать pdf или html?
есть, например, проект на яве. Задача - генерить динамически пдф и док в зависимости от данных клиента из БД.
Делаешь шаблон для пдф и док в xslt, из базы генеришь xml, натягиваешь одно на другое и отдаешь клиенту.
Причем тут php я не понял.
Можно-то оно можно, но вот делать мне нечего больше, кроме как вручную по нодам ходить и в стрингбилдер аппендить.
чем генерация xml кодом на java + преобразование xslt лучше чем сразу на java генерация нужного представления на java? разве xslt - более мощный язык?
а чё типа в питоне нет других инструментов? как ты тогда собрался xml генерировать?
чем сразу на java генерация нужного представления на java
Посмотри, например, apache fop.
Ты общаешься с джавистом. О питоне он только знает, что там есть "%s". Инструменты есть.
есть, например, проект на яве. Задача - генерить динамически пдф и док в зависимости от данных клиента из БД.Пдф проще всего генерить конвертацией из html. Docx я генерил просто текстовым шаблонизатором - делал руками в Word эталонный документ, и потом зафигачивал туда инструкции шаблонизатора.
а вот рядом тоже apache
без всяких StringBuffer и без XML
http://svn.apache.org/viewvc/pdfbox/trunk/examples/src/main...
Ты общаешься с джавистом. О питоне он только знает, что там есть "%s". Инструменты есть.Какие?
Для получения doc и pdf интересно.
да и даже тут, чтобы сгенерить сложную пдфку с кучей таблиц придется до фига кода написать, который хрен потом разберешь, нежели в случае xslt-fo, где все интуитивно понятно.+
дык а чтоб таблицы описать в xml, кучи кода не нужно?
Есть библиотеки, которые напрямую из объектов делают.
но потом же надо оформление писать на xslt - а это разве удобнее чем на java?
я имею в виду всякие штуки: типа объект должен занимать две строки, такое-то поле в первой, а такие-то - во второй в таком-то порядке, а если есть свойство AAA, то надо поставить звёздочку и добавить ещё строчку во вторую таблицу
ну то есть я верю что на java это может быть ещё хуже, чем на xslt (хотя последний вообще непригоден для человека), но на нормальном-то языке вроде питона и пхп точно должно быть проще
По мне, такие вещи напоминают gwt и иже с ними.
А вынесение статики css,js.html, xml за бизнес-код выглядит логичным.
foreach $a ($Array1) {
$Table1->add_line(new Line($a->field1, $a->field2));
var $l2 = new Line($a->field4, $a->field3);
if ($a->hasAAA()) {
$l2->add_column('*');
$Table2->add_line(new Line($a->special_attribute()));
}
$Table1->add_line($l2);
}
написать такое с разбегу на почти-XSLT можно? насколько монструозное будет преобразование?
А вынесение статики css,js.html, xml за бизнес-код выглядит логичным.
в отдельную директорию (пакет) вынеси это преобразование, проблем-то
Я кстати на первой официальной работе делал тулзу преобразования xslfo в pdf. Называлась XEP - русские делали
Для получения doc и pdf интересно.
Для генерации печатной отчетности (недельная, месячная, квартальная, полугодовая...) юзаю fpdf (правда из-за необходимости логотипа пришлось целый PIL установить, ну, это так, лирика).
По doc-ам ничего сказать не могу. Не было потребности.
Для генерации печатной отчетности (недельная, месячная, квартальная, полугодовая...) юзаю fpdf (правда из-за необходимости логотипа пришлось целый PIL установить, ну, это так, лирика).Ну это все поделки, которыми нормальный pdf не сделать. Я знаю один нормальный способ без xslfo - вызывать ТеХ.
По doc-ам ничего сказать не могу. Не было потребности.
Та же самая ботва, нормально работающей библиотеки нет.
"с разбегу" это зависит от того, как ты часто этим пользуешься и много ли примеров для копипасты.
не руками же писать такое
Оставить комментарий
MarizzaMarizza
Столкнулась со следующей практической задачей: нужно заняться поиском авиабилетов, но поиск сильно осложнен тем, что я пока не знаю ни точных дат поездки, ни куда я еду. Вот такое классическое "найди то, не знаю что".Перебирать на поисковиках типа skyscanner или momodo все даты - это я состарюсь раньше, чем закончу.
В связи с этим возникла идея автоматизировать процесс - не зря же я учила питон.
Думала взять тупо в лоб - сделать запрос и спарсить страничку. И тут-то меня ждал облом.
Возьмем, например, такой запрос:
http://awd.momondo.ru/flightsearch/?Search=true&TripType=4&SegNo=1&SO0=MOW&SD0=L&SDP0=15-01-2016&AD=1&TK=ECO&NA=false#Search=true&TripType=1&SegNo=1&SO0=MOW&SD0=L&SDP0=15-01-2016&AD=1&TK=ECO&DO=false&NA=true
Допустим, нас интересует только самый дешевый рейс (тот, который в красной шапке таблицы). Смотрим код этого элемента и видим:
А вот что мы видим для класса info:
И тут мысль останавливается. Как извлечь отсюда значение нужной переменной (видимо это formatted.fee)?