Как получить элемент HTML с учетом более позднего содержимого другого тега, а не класса?

Я преобразовываю HTML в красивый и аккуратный CSV. У меня есть файл, полный таблиц и с несколькими классами. У меня есть три типа таблиц, и их структура одинакова. Единственная разница заключается в содержимом элемента «th», который идет после интересующего меня элемента. Как я могу получить только содержимое таблиц с определенным текстом в «th» («text_that_I_want_to_get»)? Есть ли способ вставить класс с R внутри каждого типа таблицы?

Тип 1 таблицы

 <tr>
    <th class="array">text_that_I_want_to_get</th>
    <td class="array">
        <table>
            <thead>
                <tr>
                    <th class="string">name</th>
                    <th class="string">mean</th>
                    <th class="string">stdev</th>
                </tr>
            </thead>
            <tbody>

Тип 2 таблицы

<tr>
    <th class="array">text_that_I_want_to_get</th>
    <td class="array">
        <table>
            <thead>
                <tr>
                    <th class="string">name</th>
                    <th class="array">answers</th>
                </tr>
            </thead>
            <tbody>

Тип 3 таблицы

<tr>
    <th class="array">text_that_I_want_to_get</th>
    <td class="array">
        <table>
            <thead>
                <tr>
                    <th class="string">Reference</th>
                </tr>
            </thead>
            <tbody>

person polo    schedule 16.06.2020    source источник
comment
Являются ли html-коды символьными объектами в R? если да, то вы можете попробовать sub(".*<th class="array">(.*)</th>.*","\\1", My_HTML_String)   -  person Daniel O    schedule 16.06.2020
comment
Я не думаю, что это будет работать должным образом. Меня интересует не только содержимое внутри th (text_that_I_want_to_get), но и содержимое после tbody (которое огромно, и поэтому я его не выложил)... И таких таблиц, как эти и У меня нет их позиции в HTML   -  person polo    schedule 16.06.2020
comment
Вы должны опубликовать желаемый результат. Непонятно, что вы пытаетесь извлечь.   -  person Daniel O    schedule 16.06.2020


Ответы (1)


Вам нужны следующие три пути xpath:

xpath1 <- "//td[table[./thead/tr/th/text() = 'stdev']]/preceding-sibling::th"
xpath2 <- "//td[table[./thead/tr/th/text() = 'answers']]/preceding-sibling::th"
xpath3 <- "//td[table[./thead/tr/th/text() = 'Reference']]/preceding-sibling::th"

Они находят узел td, который находится в корне каждого из трех типов таблиц, а затем находят предшествующий элемент th с нужным текстом.

Итак, чтобы получить text_that_I_want_to_get для таблицы типа 1, вы делаете:

read_html(url) %>% html_nodes(xpath = xpath1) %>% html_text()
#> [1] "text_that_I_want_to_get"

И вы можете сделать то же самое с xpath2 и xpath3, чтобы получить текст из таблицы типа 2 и таблицы типа 3.

person Allan Cameron    schedule 16.06.2020
comment
Моя цель на самом деле получить текст внутри th (text_that_I_want_to_get), поэтому я не могу написать его внутри xpath1. Кроме того, таблицы каждого типа должны быть разделены. Например, в первый раз я получу только все таблицы типа 1. - person polo; 18.06.2020
comment
@polo в таком случае, чем это отличается от другого вашего вопроса, на который я ответил в stackoverflow.com/questions/62390373/, за исключением того, что вы используете @class = 'string' в xpath? - person Allan Cameron; 18.06.2020
comment
Это другое, потому что в то время мне приходилось вручную добавлять классы type1, type2 и type3 в мой HTML. Я мог бы добавить классы, потому что содержимое внутри th различается для каждого типа (имя, среднее значение, стандартное отклонение для типа 1, имя, ответы для типа 2, ссылка для типа 3). Моя цель не открывать HTML вручную и исправлять все в R - person polo; 18.06.2020
comment
@polo, так вам нужен код, который определяет, с каким типом таблицы вы имеете дело, и вставляет class = "type1" или class = "type 2" и т. д. в тег таблицы? - person Allan Cameron; 18.06.2020
comment
Да, он может вставить класс type1 или type2 или type3 с учетом th (имя, среднее значение, stdev для типа 1; имя, ответы для типа 2; ссылка для типа 3). Или он может получить th (text_that_I_want_to_get) с учетом следующего th (имя, среднее значение, stdev для типа 1; имя, ответы для типа 2; ссылка для типа 3) - person polo; 18.06.2020
comment
@polo Я добавил существенное редактирование, которое, надеюсь, сделает то, что вам нужно. - person Allan Cameron; 18.06.2020
comment
Спасибо за обновление. После добавления класса идея заключалась в том, чтобы получить содержимое внутри первого (text_that_I_want_to_get), а не загружать HTML. Но пока код здесь тоже не работал... - person polo; 19.06.2020
comment
@polo, так тебе нужно писать классы, или ты был бы рад просто получить текст, или сделать и то, и другое? Непонятно, зачем вам писать классы в таблицы, если вы никуда не сохраняете html. Приведенный выше код работает для моего примера и для вашего примера. Может быть, вы можете поделиться фактическим HTML или URL-адресом, который вы пытаетесь очистить? Я, конечно, могу это сделать, но не с информацией, которую вы здесь дали. - person Allan Cameron; 21.06.2020
comment
Я был бы рад просто получить текст, но это нужно учитывать (имя, среднее значение, stdev для типа 1; имя, ответы для типа 2; ссылка для типа 3). Или он будет вставлять класс с целью получить текст внутри первого числа каждого типа. - person polo; 22.06.2020
comment
@поло я понимаю. Для этого не нужно записывать класс в таблицу. Вам просто нужны xpaths, которые определяют правильные типы таблиц и работают в обратном направлении к th . Смотрите мое обновление. - person Allan Cameron; 22.06.2020
comment
Если это не сработает, вам нужно будет обновить, чтобы показать фактический html, так как это работает для ваших примеров. - person Allan Cameron; 22.06.2020