Браузерную - потому что с авторизацией есть некоторые трудности, к тому же не хочется возиться с защитой от ботов. Выполнение в браузере обе проблемы в значительной степени решает. Если данных для сбора не очень много, и торопиться некуда - отличный вариант.
В качестве бонуса - пишем на приятном языке JavaScript, для части операций используем удобный поиск по готовому DOM-дереву. В качестве еще одного бонуса - легко сделать "полуручной" режим, чтоб не приходилось писать код подо все, чем нужно управлять.
Для реализации выбрал Greasemonkey, ибо просто и быстро. Себе на память записываю workflow и чуть-чуть тонкостей.
- Открываем Firefox (о да, у меня с некоторых пор вместо него открыт другой браузер) и ставим Greasemonkey, если еще нет.
- Клик по обезьянке / "Создать скрипт"
- Вбиваем название, маски для включения (можно с *) и проч.
- Выбираем текстовые редактор, в котором мы пишем код (у меня jEdit)
- Ура, перед нами - голенький и пустой юзерскрипт
В качестве шаблона можно использовать что-то такое:
// ==UserScript==
// @name MyParser
// @namespace myparser
// @description Very Good Parser
// @include http://site.com/list*
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_xmlhttpRequest
// @version 1
// ==/UserScript==
(function() {
// здесь будет наш код
}
)();
Ниже - шаблон для гризманки-парсера, умеющего ходить по спискам. Это код, который надо вставить вместо комментария "здесь будет наш код" в примере выше :)
Методы надо заполнить кодом под конкретную задачу. Показана основная логика работы и аспекты "на память" - как при помощи GM_xmlhttpRequest делать GET-запросы в режиме AJAX, как отправлять данные через POST, как читать и устанавливать значения конфига.
// здесь будет наш код
var data_handler_url = 'http://ourserver.com/handler.php';
var grab_wait_time = 500; // задержка в пол секунды
var links = [];
function is_automode() {
return GM_getValue('myparser_automode');
}
function init() {
get_links(function() {
draw_controls();
if (is_automode()) {
// сразу начинаем
grab_next();
}
});
}
function get_links(callback) {
// собирает список ссылок, которые нужно спарсить и вызывает callback
links = [];
callback();
}
function get_next_page() {
// возвращает URL следующей страницы
}
function grab_url(url, callback) {
// скачивает страницу и отправляет результат на наш сервер
GM_xmlhttpRequest({
method: 'GET',
url: url,
onload: function(results) {
var content = results.responseText;
// тут какая-то обработка, проверка правильности и т.д.
// а теперь - отправляем к нам на сервер
GM_xmlhttpRequest({
url:data_handler_url,
method:'POST',
headers: {"Content-Type": "application/x-www-form-urlencoded"},
data:'url='+encodeURIComponent(url)+'&content='+encodeURIComponent(content),
onload: callback
});
}
});
}
// взять первую ссылку в списке, спарсить ее и вызвать себя через таймаут
// если ссылки кончились, а мы в авторежиме - перейти к следующей странице
function grab_next() {
var url = links.shift();
if (!url) {
if (is_automode() && get_next_page()) {
document.location.href= get_next_page();
}
return;
}
grab_url(url, function() {
// что-то пишем в окошко управления
// и грабим дальше
setTimeout(grab_next, grab_wait_time);
});
}
function draw_controls() {
// рисует окошко для управления процессом
var controls = document.body.appendChild(document.createElement('div'));
// стили, кнопка "старт/стоп" и т.д.
// ...
// а теперь - галка "авторежим"
var inp = controls.appendChild(document.createElement('input'));
inp.type = 'checkbox';
inp.checked = is_automode();
inp.addEventListener('click', function() {
GM_setValue('myparser_automode', this.checked);
});
}
Конечно, для промышленных парсеров такой подход не годится, но если нужно стащить что-то мелкое, не тратя часы на кодинг - самое то.
Давно мы не вспоминали про хипстеров. А пора бы. В связи с этим вопрос: может ли хипстер работать сантехником? Если меня читают хипстеры-сантехники - во-первых, напишите в комментах, во-вторых - зайдите на сайт, где предлагают канализационные насосные станции и много другого оборудования, которое используется для очистных сооружений. Хауди-хо!