Dubrowsky
Хроники одного дупла
Блогово  →  WebDev  → 

Как написать парсер для Greasemonkey: AJAX, GM_xmlhttpRequest

29 Ноября 2012 года

Мне тут понадобилось для рабочих нужд нафигачить небольшую браузерную приблуду, которая собирает инфу и шлет в наше хранилище. Под катом - заготовки кода и чуть-чуть пояснений.

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

В качестве бонуса - пишем на приятном языке JavaScript, для части операций используем удобный поиск по готовому DOM-дереву. В качестве еще одного бонуса - легко сделать "полуручной" режим, чтоб не приходилось писать код подо все, чем нужно управлять.

Для реализации выбрал Greasemonkey, ибо просто и быстро. Себе на память записываю workflow и чуть-чуть тонкостей.

  1. Открываем Firefox (о да, у меня с некоторых пор вместо него открыт другой браузер) и ставим Greasemonkey, если еще нет.
  2. Клик по обезьянке / "Создать скрипт" 
  3. Вбиваем название, маски для включения (можно с *) и проч.
  4. Выбираем текстовые редактор, в котором мы пишем код (у меня jEdit)
  5. Ура, перед нами - голенький и пустой юзерскрипт

В качестве шаблона можно использовать что-то такое:

// ==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);
	});
}

Конечно, для промышленных парсеров такой подход не годится, но если нужно стащить что-то мелкое, не тратя часы на кодинг - самое то.

Давно мы не вспоминали про хипстеров. А пора бы. В связи с этим вопрос: может ли хипстер работать сантехником? Если меня читают хипстеры-сантехники - во-первых, напишите в комментах, во-вторых - зайдите на сайт, где предлагают канализационные насосные станции и много другого оборудования, которое используется для очистных сооружений. Хауди-хо!

Камменты

programmingmaster28.07.2013, 11:28#
Можно глянуть тут программирование

Написать коммент: памятка постеру

 

Крутые посты wtf??? →

02.10.2012 · 90 камментов · рейтинг 19.75
15.02.2013 · 22 каммента · рейтинг 10.19
28.04.2008 · 44 каммента · рейтинг 9.84
23.01.2013 · 19 камментов · рейтинг 9.4
30.01.2013 · 13 камментов · рейтинг 7.79

Последне камменты

18.04.2017  ДубрОбработка кликов и цели в Яндекс.Метрике, улучшенный вариант: Вячеслав, блин, я там скобку потерял =) Обновил, ...
17.04.2017  Вячеславтам же: вот http://www.totalat.ru/service/remont-akpp-bmw/
17.04.2017  Вячеславтам же: Вашу версию вставил. Даже alert проверочный вывод...
17.04.2017  Вячеславтам же: То что вы там запостили это вместо последнего куск...
17.04.2017  Дубртам же: Привет! 1) код лучше запостить куда-нибудь на ht...

Статсы