Помогите разобраться - как извлечь информацию со страницы?
Вот такое классическое "найди то, не знаю что".Перебирать на поисковиках типа skyscanner или momodo все даты - это я состарюсь раньше, чем закончу. В связи с этим возникла идея автоматизировать процесс - не зря же я учила питон.как именно? какие данные ты хочешь получить и что они тебе дадут в плане выбора путешествия?
пс. питона в топку. юзай грисманки
Бешеные аяксы...
Особо не разбирался, но, судя по тому, как у них там всё наворочено, лично я бы на их месте тебе даже адресов скриптов своих просто так не показал, чтоб знать хотя бы, куда эти аяксы ломятся
))
Ну можно, конечно, проследить, кто и куда ломится, но там тоже наверняка стоит защита по кукам или сессиям
Так что грейсманки, да...
Особо не разбирался, но, судя по тому, как у них там всё наворочено, лично я бы на их месте тебе даже адресов скриптов своих просто так не показал, чтоб знать хотя бы, куда эти аяксы ломятся
))Ну можно, конечно, проследить, кто и куда ломится, но там тоже наверняка стоит защита по кукам или сессиям
Так что грейсманки, да...
Вы простите блондинку, но предполагается, что грейсманки сможет мне выцепить значение этой переменной? Или что он будет делать поиск? Если поиск, то, боюсь, это не совсем то, потому что данные все равно надо куда-то выгружать, а в этом как раз и есть основная проблема - неясно, как это делать.
Я хотела бы следующее:
- как минимум - пробежать по всем датам и всем интересующим меня направлениям и выгрузить минимальные цены в файлик, чтобы потом просто посмотреть файлик и понять, в каком месяце и куда стоит лететь.
- как максимум - выгрузить не только самый дешевый, но по паре других удобных для меня рейсов (например, не больше одной пересадки и переседка не дольше 3-4 часов). Чтобы потом в спокойной обстановке это изучить.
Я хотела бы следующее:
- как минимум - пробежать по всем датам и всем интересующим меня направлениям и выгрузить минимальные цены в файлик, чтобы потом просто посмотреть файлик и понять, в каком месяце и куда стоит лететь.
- как максимум - выгрузить не только самый дешевый, но по паре других удобных для меня рейсов (например, не больше одной пересадки и переседка не дольше 3-4 часов). Чтобы потом в спокойной обстановке это изучить.
Тогда не уверен, что оно поможет. Но я с ним знаком только теоретически.
Ну вот чтоб в файлик - точно надо разбираться, куда оно какие запросы шлёт, что в этих запросах передаёт браузер, что от этих запросов ожидает бекенд.. А потом уже их же и отправлять скриптом через тот же cURL, к примеру.
Ну вот чтоб в файлик - точно надо разбираться, куда оно какие запросы шлёт, что в этих запросах передаёт браузер, что от этих запросов ожидает бекенд.. А потом уже их же и отправлять скриптом через тот же cURL, к примеру.
Самое удобное - берешь phantom.js (это google chrome с обрезанным GUI, собранный в один бинарник и позволяющий писать скрипты типа "открыть такой-то url, выдернуть данные, выплюнуть их в stdout". Пишешь скрипт, который открывает нужный тебе сайт, дожидается окончания аякс запросов, и выдирает все данные через DOM API.
Питон не поможет, правда - нужно минимальное знание js.
Питон не поможет, правда - нужно минимальное знание 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 - этой переменной там нет. Видимо, специально прячут от таких, как я.
Федя, я ж думала, там все просто! А оказалось непросто...
Посмотрела js файлы, которые есть на momondo.ru и momondo.net - этой переменной там нет. Видимо, специально прячут от таких, как я.Ну вот даже собсно строки "flightRenderer" не видать в открытом тексте.
Есть, правда, кусок кода
<script type="text/javascript">_MomondoTripType='';_MomondoFlightSearchUrl='/multicity/';_DefaultResultView=0;_DefaultOverview='';_FlightRedirectBehavior=3</script>
Вполне возможно, что как раз по этому "/multicity/' еще кусок JS и отдается. Ну или еще примерно в таких местах. В общем, интересно, но лично мне разбираться точно лень
))Перечитала твой пост раза три. Кажется, поняла, что надо делать, но не уверена. Пойду курить мануалы.
2 l0st: я знаю про этот функционал, но мне показалось, что он не особо точен. Самый интерес представляют вещи типа ошибок авиакомпаний (типа - добавь третий сегмент и получи три билета по цене в два раза ниже, чем за два). В идеале написать бы поисковик для таких штук. Тут скайсканнер не поможет - он не умеет искать составные маршруты.
Хотя для решения конкретно моей практической задачи твое предложение, пожалуй, самое быстро реализуемое.
 
Ну и когда я попыталась забрать данные с momondo скриптом, мне уже стало интересно, как это сделать.
2 l0st: я знаю про этот функционал, но мне показалось, что он не особо точен. Самый интерес представляют вещи типа ошибок авиакомпаний (типа - добавь третий сегмент и получи три билета по цене в два раза ниже, чем за два). В идеале написать бы поисковик для таких штук. Тут скайсканнер не поможет - он не умеет искать составные маршруты.
Хотя для решения конкретно моей практической задачи твое предложение, пожалуй, самое быстро реализуемое.
 Ну и когда я попыталась забрать данные с momondo скриптом, мне уже стало интересно, как это сделать.
Скорее всего там есть нормальное rest apiПоверхностным поиском не выявлено.
Может, быстрее у них спросить? И если он есть, то и воспользоваться?

Всё довольно просто. Сначала он идёт сюда (параметры поиска передаются через Referer):
http://awd.momondo.ru/api/3.0/FlightSearch
и получает в json идентификатор скролла (параметр SearchId):
После этого порциями по этому url:
http://awd.momondo.ru/api/3.0/FlightSearch/880a08fe-655e-45ec-8aad-801f160bf379/8/true
получает результаты поиска:
Объединяет порции в один массив, сортирует по цене и отображает.
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
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...
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 часов). Чтобы потом в спокойной обстановке это изучить.скайсканер или авиасейлс разве неумеют это из коробки?
Если что, то skyscanner имеет возможность поиска билетов без дат и конкретных городов.
Достаточно при выборе даты выбрать "Весь месяц", а в поле куда выбрать "Везде", дальше даст возможность выбрать страну и дату с самыми дешевыми билетами =)
Достаточно при выборе даты выбрать "Весь месяц", а в поле куда выбрать "Везде", дальше даст возможность выбрать страну и дату с самыми дешевыми билетами =)
Я опять застопрорилась.
Код:
 
В ответ радостно получаю "Ready". И все.
Если добавляю "http.client.HTTPConnection.debuglevel = 1", вижу вот что:
 
Мой Referer передался, но, видимо, сервер его не принял, так что ли? Потому что почему иначе он не передал json? Или, может, ему нужны еще какие-то заголовки? Может, он user-agent видит и злорадно меня посылает?
Код:
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()
Ой, я не пролистал до тела запроса.
Почему-бы не использовать API какого-нибудь сервиса?
http://business.skyscanner.net/portal/en-GB/Documentation/Fl...
http://support.travelpayouts.com/hc/ru/sections/200613133-%...
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 в браузере?
Расскажите, как вы смотрели, какие запросы шлет сайт - через 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
- получить авторов этих статей и всех тех, кто их комментировал
- получить регион из профиля для каждого контакта
- отфильтровать тех, кто из Одессы
- написать каждому вопросы по статье
- получить с хабра все статьи из хаба 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 сдохла, но пока чего-то универсального, чтобы и пдфки, и доки, html  или просто текст для e-mail рассылок генерить не нашел. Плюс нативная поддержка xslt1 в оракле.
Есть решения для каждой задачи по отдельности.
Есть решения для каждой задачи по отдельности.
чем сейчас xslt лучше чем просто взять и написать хоть даже на php? 

Ну а зачем в проект на яве или питоне вкорячивать (прости госсподи) пхп?
так напиши на питоне
что там, нет библиотек чтоб сделать pdf или html?
что там, нет библиотек чтоб сделать pdf или html?
я в самом деле плохо понимаю вопрос.
есть, например, проект на яве. Задача - генерить динамически пдф и док в зависимости от данных клиента из БД.
Делаешь шаблон для пдф и док в xslt, из базы генеришь xml, натягиваешь одно на другое и отдаешь клиенту.
Причем тут php я не понял.
есть, например, проект на яве. Задача - генерить динамически пдф и док в зависимости от данных клиента из БД.
Делаешь шаблон для пдф и док в xslt, из базы генеришь xml, натягиваешь одно на другое и отдаешь клиенту.
Причем тут php я не понял.
Можно-то оно можно, но вот делать мне нечего больше, кроме как вручную по нодам ходить и в стрингбилдер аппендить.  

чем генерация xml кодом на java + преобразование  xslt лучше чем сразу на java генерация нужного представления на java? разве xslt -  более мощный язык?
а чё типа в питоне нет других инструментов? как ты тогда собрался xml генерировать?
я не понимаю, что значит 
 
Посмотри, например, apache fop.
чем сразу на java генерация нужного представления на java
Посмотри, например, apache fop.
Ты общаешься с джавистом. О питоне он только знает, что там есть "%s". Инструменты есть.
есть, например, проект на яве. Задача - генерить динамически пдф и док в зависимости от данных клиента из БД.Пдф проще всего генерить конвертацией из html. Docx я генерил просто текстовым шаблонизатором - делал руками в Word эталонный документ, и потом зафигачивал туда инструкции шаблонизатора.
> Посмотри, например, apache fop
а вот рядом тоже apache
без всяких StringBuffer и без XML
http://svn.apache.org/viewvc/pdfbox/trunk/examples/src/main...
а вот рядом тоже apache
без всяких StringBuffer и без XML
http://svn.apache.org/viewvc/pdfbox/trunk/examples/src/main...
Ты общаешься с джавистом. О питоне он только знает, что там есть "%s". Инструменты есть.Какие?
 Для получения doc и pdf интересно.
я видел, поэтому написал, что по отдельности есть средства. xslt же универсален.
да и даже тут, чтобы сгенерить сложную пдфку с кучей таблиц придется до фига кода написать, который хрен потом разберешь, нежели в случае xslt-fo, где все интуитивно понятно.+
да и даже тут, чтобы сгенерить сложную пдфку с кучей таблиц придется до фига кода написать, который хрен потом разберешь, нежели в случае xslt-fo, где все интуитивно понятно.+
дык а чтоб таблицы описать в xml, кучи кода не нужно?
Есть библиотеки, которые напрямую из объектов делают.
ну ясно что ты сделаешь таблицу из объектов
но потом же надо оформление писать на xslt - а это разве удобнее чем на java?
я имею в виду всякие штуки: типа объект должен занимать две строки, такое-то поле в первой, а такие-то - во второй в таком-то порядке, а если есть свойство AAA, то надо поставить звёздочку и добавить ещё строчку во вторую таблицу
ну то есть я верю что на java это может быть ещё хуже, чем на xslt (хотя последний вообще непригоден для человека), но на нормальном-то языке вроде питона и пхп точно должно быть проще
но потом же надо оформление писать на xslt - а это разве удобнее чем на java?
я имею в виду всякие штуки: типа объект должен занимать две строки, такое-то поле в первой, а такие-то - во второй в таком-то порядке, а если есть свойство AAA, то надо поставить звёздочку и добавить ещё строчку во вторую таблицу
ну то есть я верю что на java это может быть ещё хуже, чем на xslt (хотя последний вообще непригоден для человека), но на нормальном-то языке вроде питона и пхп точно должно быть проще
не понимаю, в чем непригодность. 
По мне, такие вещи напоминают gwt и иже с ними.
А вынесение статики css,js.html, xml за бизнес-код выглядит логичным.
По мне, такие вещи напоминают gwt и иже с ними.
А вынесение статики css,js.html, xml за бизнес-код выглядит логичным.
ну вот на псевдокоде (почти perl/php/js) то что я сказал
написать такое с разбегу на почти-XSLT можно? насколько монструозное будет преобразование?
в отдельную директорию (пакет) вынеси это преобразование, проблем-то
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)?