luni, 26 noiembrie 2007

Crawler pentru Blogger.com ( tema 2 IE)

Pentru tema 2 mi-am ales analiza site-ului blogger.com
Scopul temei este de a scrie un crawler care sa obtina diverse tipuri de relatii dintre utilizatori/bloguri.

Ca tehnologie folosita am ales Java si Mysql.

Prima problema pe care am intalnit-o a fost cand am incercat sa obtin un obiect DOM alcatuit prin parsarea html-ului unui blog. Html-ul nu este conform standardelor si nu am reusit sa-l parsez.
Rezolvarea problemei a fost utilizarea JTidy un parser HTML care permite corectarea greselilor de sintaxa.
Dupa apelul :
document = tidy.parseDOM(urlConnection.getInputStream(), outputStream);
vom avea in document structura paginii.
Atentie: dupa incercari repetate am descoperit ca daca in loc sa apelez metoda parseDOM care returneaza DOM-ul asociat stream-ului parsat se foloseste metoda parse care doar scrie stream-ul parsat intr-un output stream, urmata de creearea unui DOM din acel stream se pot intampina dificultati la creearea DOM-ului.

Din acest moment totul ar fi trebuit sa decurga usor prin folosirea XPath-ului pt a gasi informatiile relevante.
Search-uri pe expresii de tipul expression = "//a[@class=\"comment-link\"]";
care returneaza toate nodurile < a > oriunde s-ar afla, cu parametrul "class" = "comment-link" returneaza liste de noduri sau noduri ce pot fi prelucrate usor.
De exemplu urmatoarea bucata de cod cauta toate comments-urile si le adauga intr-o lista de comments dupa ce in prealabil a scos atributele pop-up din url.

expression = "//a[@class=\"comment-link\"]";
nodeList = (NodeList) xpath.evaluate(expression, document,
XPathConstants.NODESET);
for (int i = 0; i < nodeList.getLength(); i++) {
aux = nodeList.item(i);

String auxS = aux.getAttributes().getNamedItem("href")
.getNodeValue();
// daca linkul e de tip popup scoate parametrul popup
if (auxS.indexOf("&isPopup=true") > 0)
auxS = auxS.substring(0, auxS.indexOf("&isPopup=true"));
// adaugam comment-ul in lista de comments
if (!(aux.getChildNodes().item(0).getNodeValue().indexOf("0") >= 0))
comments.add(auxS);

}


Insa cu aceasta ocazie am observat ca nu toate paginile blogger sunt formate pe baza aceluiasi template html. Se pare ca exista o diferenta intre vechile pagini blogger 1.0 si noile blogger 2.0.
De exemplu link-urile din textul din entry-uri este gasit cu string-ul XPATH:
expression = "//div[@class=\"post-body entry-content\"]/a";

in timp ce in alta versiune este gasit cu:
expression = "//div[@class=\"post-body\"]/p/a";

Un alt lucru pe care l-am observat este ca daca pentru majoritatea paginilor structura dupa corectarea paginii cu JTIDY este aceeasi doar ca au fost inchise toate tag-urile, corectate toate greselile de semantica si sintaxa samd, pagina de profile ale utilizatorilor sufera o transformare radicala dupa "curatarea" cu JTIDY.

De aceea trebuie sa fim atenti cand folosim JTIDY si sa analizam structura paginii obtinute si nu a paginii initiale.

O alta problema este ca datorita structurii customizabile a template-urilor blogger nu putem fi siguri ca toate informatiile pe care le cautam se gasesc intotdeauna pe fiecare pagina.De exemplu am gasit in cursul parsarii bloguri care nu aveau pe ele profilul userilor lucru ce mi-a creeat probleme, sau profile care nu erau publice.

O analiza atenta va reusi totusi sa extraga extrem de multe informatii din paginile blogger.

Codul pentru tema mea se va gasi dupa expirarea termenului limita de trimitere a temelor aici.

Ca un ultim sfat: acest proiect ar fi fost mult mai usor de realizat in python.

Niciun comentariu: