Metody hook
Te metody działają na zasadzie hooków. Implementacja tych metod pozwala kontrolować pracę scrapera na różnych etapach, od inicjalizacji do zniszczenia obiektu
Implementacja wszystkich metod oprócz parse jest opcjonalna
async parse(set, results)
Metoda parse realizuje główną logikę przetwarzania zapytania i otrzymywania wyniku scrapowania, jako argumenty przekazywane są:
set- obiekt z informacjami o zapytaniu:set.query- ciąg tekstowy zapytaniaset.lvl- poziom zapytania, domyślnie0
results- obiekt z wynikami, które należy wypełnić i zwrócić z metodyparse()- scraper powinien sprawdzać obecność każdego klucza w obiekcie results i wypełniać go tylko wtedy, gdy istnieje, w ten sposób optymalizowana jest prędkość i scrapowane są tylko te dane, które są używane w tworzeniu wyniku
resultszawiera klucze niezbędnych zmiennych flat z wartościąnone, co domyślnie oznacza, że wynik nie został otrzymany, a także klucze zmiennych-tablic (arrays) z wartością w postaci pustej tablicy, gotowej do wypełnieniaresults.successpowinien być ustawiony na wartość1przy pomyślnym przetworzeniu zapytania, domyślnie wartość0, co oznacza, że zapytanie zostało przetworzone z błędem
Rozważmy to na przykładzie:
class JS_HTML_Tags extends BaseParser {
static defaultConf = {
results: {
flat: [
['title', 'Title'],
],
arrays: {
h2: ['H2 Headers List', [
['header', 'Header'],
]],
}
},
...
};
async parse(set, results) {
// Pobieramy zawartość strony HTML, której adres został przekazany w zapytaniu
const {success, data, headers} = await this.request('GET', set.query);
// Sprawdzamy powodzenie i typ data, przy poprawnej obsłudze stron HTML powinniśmy otrzymać typ 'string', w przeciwnym razie A-Parser zwraca obiekt typu Buffer
if (success && typeof data == 'string') {
let matches;
// Sprawdzamy konieczność zebrania title i zapisujemy wartość
if (results.title && matches = data.match(/<title[^>]*>(.*?)<\/title>/))
results.title = matches[1];
// Sprawdzamy konieczność zebrania h2
if (results.h2) {
let count = 0;
const re = /<h2[^>]*>(.*?)<\/h2>/g;
while(matches = re.exec(data)) {
// Zapisujemy w pętli wszystkie znalezione tagi h2
results.h2.push(matches[1]);
}
}
// Powiadamiamy o pomyślnym zakończeniu scrapowania
results.success = 1;
}
// Zwracamy przetworzone wyniki
return results;
}
};
Zauważ, że możesz tworzyć własne funkcje i metody dla lepszej organizacji kodu:
function Answer() {
return 42;
}
class JS_HTML_Tags extends BaseParser {
...
async parse(set, results) {
results = await this.doWork(set, results);
return results;
}
async doWork(set, results) {
results.answer = Answer();
return results;
}
};
async processConf?(conf)
Ta metoda służy do przekształcania konfiguracji według określonych reguł, na przykład przy użyciu captcha zawsze musimy korzystać z sesji:
async processConf(conf) {
if (conf.useCaptcha)
conf.useSessions = 1
}
async parse(set, results) {
if (conf.useSessions)
await this.login();
}
Istnienie tej metody wynika z faktu, że A-Parser obsługuje dynamiczne pola konfiguracji i w ramach jednego zadania konfiguracja może mieć różne wartości, taki scenariusz jest możliwy w dwóch przypadkach:
- Użycie szablonów w polach konfiguracji, na przykład
[% tools.ua.random() %]dla pola User-Agent - Użycie
overridesprzy wywoływaniu jednego scrapera z drugiego dlathis.parser.request
Metoda processConf jest wywoływana raz przed init(). W przypadkach opisanych powyżej processConf jest wywoływana dodatkowo przed przetworzeniem każdego zapytania
Główne zasady stosowania processConf:
- Używaj tylko wtedy, gdy przekształcenie konfiguracji ma wpływ na wydajność
- Pamiętaj, że
initjest wykonywane raz, aprocessConfmoże być wykonywane dla każdego zapytania, w takim przypadku logika może zostać naruszona, jeśliinitzależy od zmieniających się pól konfiguracji (patrz niżej)
async init?()
Metoda init jest wywoływana raz podczas inicjalizacji bazowego obiektu scrapera, służy do wykonywania jednorazowych czynności:
- Uruchomienie przeglądarki
- Inicjalizacja menedżera sesji za pomocą metody
this.sessionManager.init() - Połączenie z bazą danych i tworzenie tabel w BD
- Odczyt danych statycznych
- I t.d.
Ponieważ metoda jest wywoływana raz, wszystkie pola konfiguracji, od których zależy init(), nie mogą być używane wspólnie z szablonami pól konfiguracji lub z overrides przy wywoływaniu this.parsers.request
async destroy?()
Metoda destroy jest wywoływana raz po zakończeniu pracy zadania, jest niezbędna do poprawnego zniszczenia otwartych zasobów:
- Zamknięcie przeglądarki
- Zamknięcie połączenia z BD
- I t.d.
async threadInit?()
Ta metoda jest uruchamiana przy inicjalizacji każdego wątku, każdy wątek stanowi kopię bazowego obiektu scrapera z własnym unikalnym this.threadId, który zaczyna się od 0 i kończy na threads_count - 1
Główne warianty zastosowania:
- tworzenie strony (karty) przeglądarki dla każdego wątku
async threadDestroy?()
Wykonywana przy zakończeniu wątku w procesie kończenia zadania, służy do zwalniania zasobów przydzielonych dla danego wątku
async afterResultsProcessor?(results)
Ta metoda jest wykonywana po przetworzeniu wyników przez: konstruktor wyników, filtrowanie i usuwanie duplikatów. Głównym zastosowaniem jest dodawanie zapytań do kolejki za pomocą metody this.query.add po zastosowaniu filtrów użytkownika; w ten sposób zrealizowane jest filtrowanie linków do przejścia (followlinks) dla scrapera
HTML::LinkExtractor