Jak napisać własnego robota internetowego cz. 1

Kiedy myślimy o robocie internetowych, sprawa wydaje się skomplikowana. Ale czy na pewno? Spróbujmy napisać robota internetowego, który będzie indeksował np. Panoramę Firm – oczywiście tylko do celów edukacyjnych. Dlaczego akurat tą stronę? Jest tam dużo powtarzających się – według szablonu – treści. Tak więc wyciągnięcie informacji będzie dla nas prostsze. A tak na marginesie, jak myślicie, jak długo zajmie zindeksowanie Google?? :-)

Jest kilka bibliotek do przetwarzania wyrenderowanych stron HTML, lub też po prostu do pobierania źródła strony. Mi do gustu najbardziej przypadł HtmlUnitSelenium. Selenium jest używane przez testerów do automatycznych testów stron internetowych, posiada przyjemny edytor – pracuje jako dodatek do Firefoxa. Wszystko generalnie można znaleźć na stronie producenta. Jego wadą jest jednak dość skromna dokumentacja, ale jakoś sobie z tym poradzimy.

No dobrze, wejdźmy na stronę: http://www.pf.pl/serwis/Biuro-Warszawa-V1_YP.html i spróbujmy z niej wyciągnąć numer telefonu, jak to zrobić? Kod i opis poniżej:

package pl.beriko.web.bot.collect;

import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.htmlunit.HtmlUnitDriver;

public class SimpleBot2 {
	private Log logger = LogFactory.getLog(getClass());

	private WebDriver driver = new HtmlUnitDriver();

	public SimpleBot2() {
		// Przygotujmy naszego robota aby odwiedził tą stronę:
		this.driver.get("http://www.pf.pl/serwis/Biuro-Warszawa-V1_YP.html");
	}

	public List getFaxes() {
		WebElement tel;

		// Na stronie jest 10 takich samych elementów reprezentujących 10 firm
		for (int i = 1; i <= 10; i++) {
			try {
				// do prostego i szybkiego określenia xpath możemy użyć Selenium
				// IDE, opis poniżej
				tel = driver.findElement(By.xpath("//span[@id='results']/div[" + i + "]/div[1]/div[3]/div[1]/p[2]/span[1]/a"));
				// tutaj otrzymujemy telefon w formacje callto:+48...(tel)
				logger.info(tel.getAttribute("href"));
				logger.info("----");
			} catch (NoSuchElementException ns) {
				// może się zdażyć, że dany element nie będzie istniał - jeden z
				// rekordów będzie w innym szablonie
			}

			tel = null;
		}

		driver.quit();

		return null;
	}

	public static void main(String[] args) {
		SimpleBot bot = new SimpleBot();
		bot.getFaxes();
	}
}

A teraz przykład jak ułatwić sobie życie za pomocą Selenium IDE. Mianowicie jak pobrać ścieżkę XPath. W przeglądarce Firefox po zainstalowaniu Selenium IDE klikamy Tools -> Selecnium IDE. Otworzy się nam okienko programu, proponuję zapoznać się z opcjami, są naprawdę przydatne i interesujące. Następnie zaznaczamy element, który nas interesuje i widzimy ścieżkę XPath. Jak klikniemy Store text (…) dodamy do edytora ścieżkę XPath i możemy sobie ją skopiować :)

Zaprezentowany obrazek troszkę się różni od tego co jest w kodzie, ale powiedzmy, że znalezienie i zrozumienie różnicy to zadanie domowe ;)

Oto co otrzymaliśmy:

 INFO [main] - callto:+48509116717
 INFO [main] - ----
 INFO [main] - callto:+48223920509
 INFO [main] - ----
 INFO [main] - callto:+48608895380
 INFO [main] - ----
 INFO [main] - callto:+48608895380
 INFO [main] - ----
 INFO [main] - callto:+48223252100
 INFO [main] - ----
 INFO [main] - callto:+48228109916
 INFO [main] - ----
 INFO [main] - callto:+48226091021
 INFO [main] - ----
 INFO [main] - callto:+48669982399
 INFO [main] - ----
 INFO [main] - callto:+48226538400
 INFO [main] - ----

Ależ to było proste, prawda?