Przejdź do treści głównej

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 zapytania
    • set.lvl - poziom zapytania, domyślnie 0
  • results - obiekt z wynikami, które należy wypełnić i zwrócić z metody parse()
    • 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
    • results zawiera 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łnienia
    • results.success powinien być ustawiony na wartość 1 przy 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 overrides przy wywoływaniu jednego scrapera z drugiego dla this.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 init jest wykonywane raz, a processConf może być wykonywane dla każdego zapytania, w takim przypadku logika może zostać naruszona, jeśli init zależ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.
ostrzeżenie

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::LinkExtractorHTML::LinkExtractor