Przejdź do treści głównej

Scrapery w JavaScript: Przegląd możliwości

Scrapery JavaScript - to możliwość tworzenia własnych, pełnoprawnych scraperów z dowolnie złożoną logiką, przy użyciu języka JavaScript. Jednocześnie w scraperach JS można również wykorzystywać całą funkcjonalność standardowych scraperów.

Przegląd

Funkcje

Wykorzystując całą moc A-Parser, można teraz napisać własny scraper/reger/poster z dowolnie złożoną logiką. Do pisania kodu używany jest JavaScript z możliwościami ES6 (silnik v8).

Kod scraperów jest maksymalnie zwięzły, co pozwala skupić się na pisaniu logiki; obsługę wielowątkowości, sieci, proxy, wyników, logów itp. A-Parser bierze na siebie. Kod można pisać bezpośrednio w interfejsie scrapera, dodając nowy scraper w Edytorze scraperów. Do pisania scraperów można również używać zewnętrznych edytorów, na przykład VSCode.

Stosowane jest automatyczne wersjonowanie podczas zapisywania kodu scrapera przez wbudowany edytor.

notatka

Praca ze scraperami JavaScript jest dostępna dla licencji Pro i Enterprise

Dostęp do Edytora scraperów JS

Jeśli A-Parser jest używany zdalnie, ze względów bezpieczeństwa Edytor scraperów JS jest domyślnie niedostępny. Aby uzyskać do niego dostęp, należy:

  • Ustawić hasło w zakładce Settings -> Global Settings
  • Dodać do config/config.txt następującą linię: allow_javascript_editor: 1
  • Zrestartować A-Parser

Instrukcja obsługi

W Edytorze scraperów tworzymy nowy scraper i nadajemy mu nazwę. Domyślnie zostanie załadowany prosty przykład, na podstawie którego można szybko przystąpić do tworzenia własnego scrapera.

notatka

Jeśli do pisania kodu używany jest zewnętrzny edytor, należy otworzyć plik edytowanego scrapera w folderze /parsers/. Struktura plików zainstalowanego programu.

Gdy kod będzie gotowy, zapisujemy go i używamy jak zwykłego scrapera: w Edytorze zadań wybieramy utworzony scraper, w razie potrzeby można ustawić wymagane parametry, konfigurację wątków, nazwę pliku itp.

Utworzony scraper można edytować w dowolnym momencie. Wszystkie zmiany dotyczące interfejsu pojawią się po ponownym wybraniu scrapera na liście scraperów lub restarcie A-Parsera; zmiany w logice scrapera są stosowane przy ponownym uruchomieniu zadania ze scraperem.

Dla każdego utworzonego scrapera domyślnie wyświetlana jest standardowa ikona, można dodać własną w formacie png lub ico, umieszczając ją w folderze scrapera w /parsers/:

Ogólne zasady działania

Domyślnie tworzony jest przykład prostego scrapera, gotowy do dalszej edycji.

files/parsers/v2-example/v2-example.ts

import { BaseParser } from 'a-parser-types';

export class JS_v2_example extends BaseParser {
static defaultConf: typeof BaseParser.defaultConf = {
version: '0.0.1',
results: {
flat: [
['title', 'HTML title'],
]
},
max_size: 2 * 1024 * 1024,
parsecodes: {
200: 1,
},
results_format: '$query: $title\\n',
};

static editableConf: typeof BaseParser.editableConf = [];

async parse(set, results) {
this.logger.put("Start scraping query: " + set.query);

let response = await this.request('GET', set.query, {}, {
check_content: ['<\/html>'],
decode: 'auto-html',
});

if (response.success) {
let matches = response.data.match(/<title>(.*?)<\/title>/i);
if (matches)
results.title = matches[1];
}

results.success = response.success;

return results;
}
}

Konstruktor wywoływany jest jednorazowo dla każdego zadania. Należy obowiązkowo ustawić this.defaultConf.results oraz this.defaultConf.results_format, pozostałe pola są opcjonalne i przyjmą wartości domyślne.

Tablica this.editableConf określa, jakie ustawienia mogą być zmieniane przez użytkownika z poziomu interfejsu A-Parser. Można używać następujących typów pól:

  • combobox - menu rozwijane. Można również utworzyć menu wyboru presetu standardowego scrapera, na przykład:
['Util_AntiGate_preset', ['combobox', 'AntiGate preset']]
  • combobox z możliwością wielokrotnego wyboru. Należy dodatkowo ustawić parametr {'multiSelect': 1}:
['proxyCheckers', ['combobox', 'Proxy Checkers', {'multiSelect': 1}, ['*', 'All']]]
  • checkbox - pole wyboru dla parametrów, które mogą mieć tylko 2 wartości (true/false)
  • textfield - pole tekstowe
  • textarea - pole tekstowe z możliwością wprowadzania wielu linii

Metoda parse jest funkcją asynchroniczną i dla każdej operacji blokującej powinna zwracać await (jest to główna i jedyna różnica w stosunku do zwykłej funkcji). Metoda jest wywoływana dla każdego zapytania trafiającego do przetwarzania. Obowiązkowo przekazywane są set (hash z zapytaniem i jego parametrami) oraz results (pusty szablon na wyniki). Należy również obowiązkowo zwrócić wypełniony results, uprzednio ustawiając flagę success.

Automatyczne wersjonowanie

Wersja ma format Major.Minor.Revision

this.defaultConf: typeof BaseParser.defaultConf = {
version: '0.1.1',
...
}

Wartość Revision (ostatnia cyfra) jest automatycznie zwiększana przy każdym zapisie. Pozostałe wartości (Major, Minor) można zmieniać ręcznie, a także resetować Revision do 0.

wskazówka

Jeśli z jakichś powodów konieczna jest zmiana Revision tylko ręcznie, wersję należy ująć w podwójne cudzysłowy ""

Pakietowe przetwarzanie zapytań

W niektórych przypadkach może być konieczne pobranie kilku zapytań z kolejki naraz i przetworzenie ich w jednym cyklu. Taki tryb we wbudowanych scraperach jest używany, gdy w jednym przejściu trzeba pobrać dane dla kilku kluczy naraz (paczką).

Aby zaimplementować taką samą funkcjonalność w scraperze JS, należy w this.defaultConf ustawić wartość bulkQueries: N, gdzie N - wymagana liczba zapytań w paczce. W takim przypadku scraper będzie pobierał zapytania paczkami po N sztuk, a wszystkie zapytania bieżącej iteracji będą zawarte w tablicy set.bulkQueries (włączając wszystkie standardowe zmienne: query.first, query.orig, query.prev itp.). Poniżej przykład takiej tablicy:

[
{
"first": "test",
"prev": "",
"lvl": 0,
"num": 0,
"query": "test",
"queryUid": "6eb301",
"orig": "test"
},
{
"first": "sprawdzenie",
"prev": "",
"lvl": 0,
"num": 1,
"query": "sprawdzenie",
"queryUid": "774563",
"orig": "sprawdzenie"
},
{
"first": "third query",
"prev": "",
"lvl": 0,
"num": 2,
"query": "third query",
"queryUid": "2bc8ed",
"orig": "third query"
}
]

Wyniki przy przetwarzaniu pakietowym należy wypełniać w tablicy results.bulkResults, gdzie każdy element jest obiektem results. Elementy w results.bulkResults znajdują się w tej samej kolejności, jaka była w set.bulkQueries.