Генерация родословного дерева на основе данных 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
Результат в виде списка:
Адам
Чингисхан
Романовы
Рюриковичи
Комментарии
Добавить комментарий