2016-08-16 3 views
0

У меня возникли проблемы с анализом html-документа. Я использую xml2, и до сих пор я довольно доволен. Но есть еще некоторые икоты, которые я хотел бы решить. Вот как я в основном разбираю мои документы:Как правильно разобрать HTML-код в R?

html.raw <- xml2::read_html('/Users/simgeh/Documents/pipeDirs/BMAS/html_withid/2014_02_17_nahles_in_paris.html')   
docContent <- xml_text(xml_find_all(html.raw, xpath="//div[@id='content']//text() 
             [not(ancestor-or-self::div[@class='docType'])] 
             [not(ancestor-or-self::h1[@class='isFirstInSlot'])] 
             [not(ancestor-or-self::div[@class='abstract'])] 
             [not(ancestor-or-self::div[@class='sectionRelated'])] 
             [not(ancestor-or-self::div[@id='contentsocial'])]")) 

В большинстве случаев получение контента (в основном длинного текста) работает нормально. Но в некоторых случаях, например, когда в статье есть ссылки, помещенные в текст, это может выглядеть как беспорядок. Разобранный текст должен выглядеть следующим образом:

Am Donnerstag (12,01). Вирд Bundesaußenminister Д-р Франк-Вальтер Штайнмайер им Auswärtigen Amt мит сэйнэны Amtskollegen AUS Großbritannien унд AUS Frankreich Джек Стро унд Филипп Дуст-Блази , sowie dem Hohen Repräsentanten der EU für die Gemeinsame Außen- und Sicherheitspolitik, Хавьер Солана, zusammenkommen. Thema des Treffens wird das iranische Nuklearprogramm sein.

но выглядит следующим образом:

Am Donnerstag (12,01). Вирд Bundesaußenminister Д-р Франк-Вальтер Штайнмайер им Auswärtigen Amt мит сэйнэны Amtskollegen AUS Großbritannien унд AUS Frankreich,

Jack Солома

und

Philippe Dou STE-Блази

, Сових дем Хохен Repräsentanten дер ЕС für умирают Gemeinsame Außen- унд Sicherheitspolitik,

Хавьер Солана

, zusammenkommen. Thema des Treffens wird das iranische Nuklearprogramm sein.

Проблема заключается в том, что внутри текста есть несколько слов, написанных на другом языке, и автор любил это указывать. Например, название «Джек Стро» ссылается следующим образом:

<span lang=\"en-GB\" xml:lang=\"en-GB\" xml:lang=\"en-GB\">Jack Straw</span> 

Everytime это происходит текст испортится. Поэтому я ищу некоторые способы улучшить качество анализируемого текста.

Возможно, я нашел решение, но оно не работает так хорошо, как надеялось. Если я удалю //text() из моей строки xpath, анализируемый текст будет выглядеть так же хорошо, как и предполагалось, но нет способа удалить нежелательный контент из контейнера. Короче говоря, [not(ancestor-or-self не работает, что оставляет текст загроможденным данными, которые я не хочу.

«короткий» иллюстрация моей проблемы:

<html> 
# a lot of html before my node I want to grab... 
<div class="Pressemitteilungen"> 
    <div class="doctype">unwanted</div> 
    <h1 class="something">unwanted</h1> 
    <p>wanted data</p> 
    <p>wanted data 
    <span lang=\"en-GB\" xml:lang=\"en-GB\" xml:lang=\"en-GB\">wanted data</span> 
    </p> 
    <p>wanted data</p> 
    <blockquote> 
    <p>wanted data</p> 
    </blockquote> 
    <p class="msSomething">wanted data</p> 
    <p class="msSomethingElse">wanted data</p> 
    <ul> 
    <li> wanted data</li> 
    </ul> 
</div> 
# a lot of stuff after my node I want to grab... 
</html> 

Причина, почему я захватить полный узел, который содержит некоторые данные мне не нужно, то, что нет никакой реальной возможности сказать, какого рода из тегов, которые я могу ожидать и, следовательно, нужно захватить. Иногда данные обертываются в <p>, в <p class="msSomething"> или <p class="msSomethingElse"> и еще несколько.Поэтому я подумал, что проще удалить ненужный материал из узла, а не индивидуально искать нужные теги. Мы также много говорим. (30.000+)

Возьмите эту PressRelease, например: http://www.bmas.de/DE/Presse/Pressemitteilungen/2014/2014_02_13_arbeitnehmerfreizuegigkeit.html

Используя вашу идею я захватить мои данные, как это:

docContent <- xml_text(xml_find_all(html.raw, xpath="(//div[@class='article-text singleview']//p[@class='MsoNormal']| 
            //div[@class='article-text singleview']//h2| 
            //div[@class='article-text singleview']//blockquote)//text()")) 

До тех пор, как я до сих пор используют //text() текст становится перепутались, как это:

[18] "\ nMinister Хасан Ademov:"
[19] «Die bulgarische Regierung шляпа Сечь Immer für die vollständige Anwendung der "
[20]" EU "
[21]" -Rechtsvorschriften zur Arbeitnehmerfreizügigkeit ausgesprochen. Unsere Position stimmt мит дер дез Europäischen Parlaments унд дер "
[22] "ЕС"
[23] "-Kommission überein - Auch Wir schätzen умереть Vorteile дер Freizügigkeit унд Ihre положительный Auswirkung Ауф кубика Wirtschaft innerhalb дер"
[24] "ЕС"
[25] ". Gleichzeitig anerkennen wir, dass mit Rechten auch immer entsprechende Pflichten verbunden sind. "

Причина этого являются аннотациями как этот <abbr title="Europäische Union">EU</abbr> в тексте Когда я удалить //text() из XPath текст отлично структурирован, но я не могу удалить ненужные данные, как это:. ([not(ancestor-or-self::div[@class='sectionRelated'])])

Так , любая помощь будет принята с благодарностью ...

+1

Не могли бы вы сделать ваш пример воспроизведения кий? Например. вы можете добавить строку типа 'html.raw <- xml2 :: read_html (" МИНИМАЛЬНЫЙ ПРИМЕР ЗДЕСЬ "', содержащий минимальное количество строк, которые генерируют * un * желаемый результат, а также пример желаемого вывода. –

+0

Я добавил базовую структуру HTML. – SimGeh

ответ

0

%%%%%% итерация = 1: не удалось (пока)

Учитывая беспорядочности ваших данных HTML, я подозреваю, что мы должны прийти к решение с итерационным способом, так что здесь мой первый выстрел:

library(xml2) 

html.raw <- xml2::read_html('<html> 
# a lot of html before my node I want to grab... 
<div class="Pressemitteilungen"> 
    <div class="doctype">unwanted 1</div> 
    <h1 class="something">unwanted 2</h1> 
    <p>wanted data 1</p> 
    <p>wanted data 2</p> 
    <p>wanted data 3</p> 
    <blockquote> 
    <p>wanted data 4</p> 
    </blockquote> 
    <p class="msSomething">wanted data 5</p> 
    <p class="msSomethingElse">wanted data 6</p> 
    <ul> 
    <li> wanted data 7</li> 
    </ul> 
</div> 
# a lot of stuff after my node I want to grab... 
</html>') 

print(docContent <- xml_text(xml_find_all(html.raw, xpath="(//p|//li)//text()"))) 

Теперь, если документ содержит больше «хотел данных» в других тегах, или, возможно, даже «нежелательные данные» в пределах ряда же тегов как «хотели данных», то, пожалуйста, обновите ваш минимальный пример с соответствующими случаями, и мы берем его оттуда.

%%%%%% итерация = 2: все ближе: D

Для конкретного пресс-релизе, что вы просто связаны, используя один обратный слеш перед p, h2 и (и удаление проблемного //text()) производит что я считаю ваш желаемый результат (я до сих пор, чтобы попытаться угадать, что вы на самом деле хотите), потому что нежелательные h2 метки «Audio» и «Weitere Informationen» заключены в еще <div class="sectionRelated">:

xpath <- "(//div[@class='article-text singleview']/p[@class='MsoNormal']| 
      //div[@class='article-text singleview']/h2| 
      //div[@class='article-text singleview']/blockquote)" 
docContent <- xml_text(xml_find_all(html.raw, xpath=xpath)) 
+0

Благодарим вас за ответ. У меня все еще возникла проблема, что текст захламлен, когда я применяю 'text()'. – SimGeh

+0

Как загромождение появляется в вашем собственном примере? –

+0

Вы можете увидеть загромождение в двух блоках блока выше. Я также описал, что может вызвать его, хотя я понятия не имею, почему ... – SimGeh