Раздел: Автоматизация управления браузером. Подраздел: Генеалогическое древо

Генерация родословного дерева на основе данных Wikidata

В прошлой статье было показано, как генерировать родословное древо на основе данных Wikipedia. Но как правильно подсказали на хабре данные лучше генерировать, используя Wikidata. К счастью, изменения в программе коснутся только класса PersonPage.
PersonPage сделаем абстрактным, а вместо конструктора создадим маленькую фабрику, которая по урлу будет определять, к какому домену относится заданный урл. В пакет ru.fonkost.pageObjects добавим два новых класса WikipediaPage и WikidataPage, которые буду дочерними для PersonPage. В этих дочерних классах будет хранится реализация для Wikipedia и Wikidata соответственно.
Из класса PersonPage выносим всю реализацию в WikipediaPage. Также переносим тесты из TestPersonPage в TestWikipediaPage.
Класс PersonPage становится таким:



public abstract class PersonPage {
    protected WebDriver driver;

    public static PersonPage createPersonPage(WebDriver driver, String link) throws Exception {
        if (link == null) {
            throw new Exception("Link can not be null");
        }
        URL url = new URL(link);
        String host = url.getHost();
        if (host.contains("wikipedia")) {
            return new WikipediaPage(driver);
        } else if (host.contains("wikidata")) {
            return new WikidataPage(driver);
        }
        throw new Exception("The page for the link " + link + " is not defined");
    }

    public abstract Person getPerson(String url) throws MalformedURLException;

    public abstract List<Person> getChildrenUrl() throws MalformedURLException;
}


Осталось только разработать класс WikidataPage.
Здесь все аналогично странице Wikipedia, только изменяются локаторы:
loadPageBy - локатор элемента, по которому определяем, что страница полностью загружена;
namePageBy - наименование страницы не меняется;
nameRuBy - русскоязычное наименование;
childrenLinks - ссылки на страницы детей;


private final By loadPageBy = By.xpath(
    "//th[@class='wikibase-entitytermsforlanguageview-language'][.='Russian']");
private final By namePageBy = By.cssSelector("#firstHeading");
private final By nameRuBy = By.xpath(
    "//div[@class='wikibase-labelview'][@lang='ru']//span[@class='wikibase-labelview-text']");
private final By childrenLinks = By.xpath(
    "//div[@id='P40']//div[@class = 'wikibase-statementview-mainsnak']//a");


Единственная доработка, которая выходит за пределы класса WikidataPage - это доработка определения корректности имени ссылки. Чтобы в древо не попадали имена, наподобие Q1687510, метод isCorrectNameUrl теперь такой:


public boolean isCorrectNameUrl() {
    Pattern p = Pattern.compile("^Q?[\\d]+.*");
    Matcher m = p.matcher(nameUrl);
    return !m.matches();
}

Конечно же, не забываем покрыть все тестами.

Результаты генерации по Wikidata


Результат в виде дерева:
Адам - 243 представителя вместо 31
Чингисхан - 405 представителей вместо 33
Романовы - 850 представителей вместо 426
Рюриковичи - 11109 представителей вместо 3507

Результат в виде списка:
Адам
Чингисхан
Романовы
Рюриковичи

Комментарии

К данной статье ещё не написан ни один комментарий.

Добавить комментарий