Closed konik32 closed 9 years ago
Postarajcie się pisać swoj moduł tak aby działał na wielu wątkach(jak najwięcej singletonów, jeśli się nie uda to dla każdego zapytania twórzcie nowy obiekt). Jeśli się nie uda to trudno, ale miejcie to na uwadze.
Wrzuciłem wstępnie interfejs (może się jeszcze coś zmienić) + model, czy są ok? Mam nadzieję że dziś uda mi się wrzucić implementację.
Nie do końca. Nie mogę pobierać z bazy wszystkich odwiedzonych dotąd linków i przesłać to w jednym Set
. Czytałeś o tym crawler4j, który Ci podesłałem? https://code.google.com/p/crawler4j/wiki/FrequentlyAskedQuestions tutaj jest napisane, że nie trzeba przechowywać odwiedzonych linków, ten crawler robi to za nas.
Zainteresujmy się w ogóle tym, czy możemy użyć czyjegoś rozwiązania w tym projekcie... Na jakiej to jest licencji i jak współgra z naszą.
Rzucę okiem czy można korzystać z bazy tego crawlera. Crawler4j jest na Apache License 2.0, czyli możemy go użyć ale trzeba umieścić gdzieś tą licencję na widoku. Dobrze że zwróciłeś uwagę :)
Powracając do przechowywania już odwiedzonych linków.
Sprawdzałem i niestety nie da się skorzystać z tego mechanizmu który ma crawler4j. On zapamiętuje to tylko w obrębie pojedynczego crawla. Można co prawda crawla zatrzymać i potem do niego powrócić, ale są z tym problemy: 1) jeśli znalazłby duplikat, to nawet go nie czyta (np. drugi raz chcielibyśmy wejść w tą samą kategorię, ale z góry nam ją odrzuca) 2) crawl by się zaczynał od któregoś miejsca na stronie, a nie od głównej
Więc trzeba zrobić zapisywanie linków w bazie i przekazywać je w Secie do WebSpidera.
No tylko trzeba też jakoś odróżnić strony, na które chcemy, żeby wszedł ponownie - np. kategorie.
Pobieranie całości do jednego seta nie podoba mi się strasznie. Już lepiej odpytywać bazę o każdy nowy znaleziony link.
@bambalooon dlatego ręcznie trzeba śledzić te linki, na które weszliśmy, a nie przez crawler4j. Więc będzie okej. @konik32 Nie wpadłem że możemy odpytywać bazę o każdy link, w sumie lepiej się to skaluje szczególnie jeśli mamy dużą historię linków w porównaniu do pojedynczego crawla (np. po 100 crawlach). Plik tekstowy z 1000 linków z gumtree ma 63 KB, sporo. To możemy zmienimy interfejs żeby zawsze odpytywał bazę?
Tak
Wrzuciłem działający kod.
Pytanie: co robimy z JAR-ami, które potrzebuje crawler4j, jest tego 5 MB - wrzucać do repo?
Co działa: można poprosić WebSpidera o ileś nowych linków z danego serwisu które zwraca. Pomija duplikaty, które obsługuje interfejs WebSpider.VisitedUrlsDatabase.
Przetestowane: na Gumtree, zrobiłem dwie crawle: 1) pierwszy poprosiłem o 1000 linków - zwrócił kategorie jak i ogłoszenia (ok.50% ogłoszeń) 2) drugi crawl znowu 1000 linków, podając te z pierwszego jako odwiedzone - znowu zwraca kategorie i ogłoszenia (ok. 75% ogłoszeń)
Co jest do zrobienia. Zostawiam to Tobie @marcibak :
Przykładowe wywołanie:
WebSpider webSpider = new WebSpiderImpl();
Set<VisitedUrl> newUrls = webSpider.crawl(new URL(
"http://www.gumtree.pl/"), 1000, new VisitedUrlsDatabase() {
@Override
public boolean isAlreadyVisited(VisitedUrl url) {
// return ...;
}
});
Dodałem nowego brancha ze zmianami interfejsu WebSpider oraz konstruktora klasy WebSpiderImpl. Metoda crawl nie przyjmuje obiektu typu VisitedUrlsDatabase. Jest to singleton i powinien być podawany w konstruktorze dlatego tam go przeniosłem. Dodatkowo konstruktor przyjmuje parametry konfiguracyjne, które pobiera z pliku properties. @worldofpiesels oceń te zmiany i jeśli niczego nie zepsuły zrób merge.