2.076 de modificări
Diferență între revizuiri ale paginii „Design doc Crawler”
Design doc Crawler (vedeți sursă)
Versiunea de la data 4 februarie 2014 14:42
, 4 februarie 2014 14:42→Proiectarea in detaliu
Linia 60: | Linia 60: | ||
Baza de date | Baza de date | ||
CrawledPage(id, timestamp, url, httpStatus, rawPagePath, parsedTextPath) | |||
Link(id, url, canonicalUrl, domain, urlHash, crawledPageId) | |||
httpStatus - HTTP status code | |||
Verificam daca linkul a fost expandat prin a vedea dacă a intrat în tabelul CrawledPage | |||
crawledPageId - același cu id de la CrawledPage, pagina în care am gasit link-ul | |||
urlHash - comparăm ca să nu inserăm același link din nou(md5(canonicalUrl)). | |||
Totuși o să avem o problemă la linkuri relative vs linkuri absolute. Putem să eliminăm partea de Domain atunci cănd procesăm linkul, dar în final trebuie să compunem linkul absolut. Trebuie ignorate linkurile care n-au extensii relevante (imagini, etc). | Totuși o să avem o problemă la linkuri relative vs linkuri absolute. Putem să eliminăm partea de Domain atunci cănd procesăm linkul, dar în final trebuie să compunem linkul absolut. Trebuie ignorate linkurile care n-au extensii relevante (imagini, etc). | ||
Nu am găsit încă o bibliotecă pentru asta asemănător cu realpath. Dacă e, facem noi un mecanism, compunem link-ul și apoi îl testăm încercând să accesăm pagina respectivă și vedem ce întoarce. | |||
=== Parsare HTML === | === Parsare HTML === | ||
* o bibliotecă pentru parsat pagini html, am folosit simple_html_dom (e mică dar își face treaba) | |||
* as merge si pe o biblioteca care face strip html tags, acum depinde ce gasim si cum se comporta cu broken html | |||
* dacă nu găsim nimic, putem trânti un regexp chior -- găsim <div>-ul în care stă conținutul care ne interesează și facem un regexp doar pentru acela. Asta va insemna ca o sa folosim regexp-uri diferite per site | |||
=== Indexer === | === Indexer === | ||
Indexer - php | Indexer - php | ||
baza de date - paris | baza de date - paris | ||
Tabele | Tabele | ||
Linia 98: | Linia 91: | ||
Cuvant | Cuvant | ||
id cuvantCuDiacritice cuvantFaraDiacritice idLexem=null (null daca nu are definitie) | |||
Freq | Freq | ||
id caleFisier idCuvant freq(de aparitie sau de cate ori apare?) | |||
UseCase | UseCase | ||
id idCuvant text (propozitii) | |||
Mecanism diacritice | Mecanism diacritice | ||
Linia 144: | Linia 135: | ||
Old Post | Old Post | ||
* să găsesc cuvinte pe care DEX nu le știe, e destul de challenging cum aș face asta rapid, dacă cuvintele sunt ordonate alfabetic, atunci e mai simplu puțin, depinde și dacă ai copii de tabele ordonate invers sau nu (așa am putea folosi LIMIT 1 pentru a opri query-ul). | |||
Cred că asta se poate face în timpul indexării. Pentru căutarea full text pe dexonline, de exemplu, indexez un cuvânt găsit cu toate lexemele de care ar putea aparține. Astfel, „copii” poate proveni din „copie” sau din „copil”. Cele care nu aparțin de niciun lexem sunt cele pe care le dorim (ai să râzi, dar și baza de definiții a dexonline conține câteva cuvinte necunoscute). | |||
Mai trebuie tratate câteva cazuri speciale: | |||
- daca avem o biblioteca toleranta la broken html, am putea face un parser general cu mai multe blocuri try-catch, (eventual logam tot ce se intampla aici), astfel evitam scrierea unei expresii regulate pentru fiecare site in parte. | * Forme contrase (am uitat exact cum se numesc), de exemplu „gândindu-” din „gândindu-se”. | ||
* Forme compuse, care adesea nu apar ca atare în dicționar: nemai+verb (doar la participiu sau la gerunziu -- nemaipomenit, nemaicrezând), prefixe ca re-, ne-, anti- etc. | |||
* Nume proprii | |||
* daca avem o biblioteca toleranta la broken html, am putea face un parser general cu mai multe blocuri try-catch, (eventual logam tot ce se intampla aici), astfel evitam scrierea unei expresii regulate pentru fiecare site in parte. | |||
* la partea de store-tuples n-aș pune definiția în DB, mai degrabă un url local de fișier. | |||
index, timestamp, URL, raw_page_path, parsed_text_path | index, timestamp, URL, raw_page_path, parsed_text_path | ||
Linia 165: | Linia 153: | ||
=== Inserarea de diacritice === | === Inserarea de diacritice === | ||
* o tabelă de cuvinte care contin diacritice (cu toate formele), eventual un associative array în memorie folosind memcached sau altceva, cu cheia *cuvantul fara diacritice* si valoarea *cuvantul cu diacritice* | |||
* pentru fiecare cuvânt parsat, verificăm dacă se poate scrie cu diacritice și îl înlocuim cu varianta respectivă. | |||
=== prelucrare tarball === | === prelucrare tarball === | ||
* daca link-urile sunt relative, ar merge crawler-ul si local, dar eu zic ca n-are rost sa functioneze la fel ca pentru parsare online, deoarece ar insemna salvarea din nou a paginii raw. In plus e mai rapid sa parcurgem toate fisierele si directoarele dintr-un director radacina. De aceea propun să avem un crawler local care doar extrage text si inserează în DB în tabelul CrawledPage. | |||
=== checkpoint & resume === | === checkpoint & resume === | ||
Ca sa nu parcurgem de mai multe ori acelasi link, ideea e sa facem hash pe linkuri si sa comparam hash-urile. | Ca sa nu parcurgem de mai multe ori acelasi link, ideea e sa facem hash pe linkuri si sa comparam hash-urile. | ||
* adaugare la panoul de monitorizare | |||
* functiuni la panoul de monitorizare cu posibilitatea de a reporni crawler-ul sau indexer-ul pe o anumita pagina/fisier text | |||
=== fisier de configurare=== | |||
===fisier de configurare=== | |||
2 variante | 2 variante | ||
Linia 195: | Linia 180: | ||
define("_KEY1_", "VAL1"); | define("_KEY1_", "VAL1"); | ||
define("_KEY2_", "VAL2"); | define("_KEY2_", "VAL2"); | ||
== Documentația Crawlerului == | == Documentația Crawlerului == |