2013-07-04 4 views
1

У меня есть HTML-файл, который содержит следующее содержание:Xpath текст() Использование функции

<div>Chapter 1. <span>Contents of chapter N1.</span> </div> 
<div>Chapter 2. <span>Contents of chapter N2.</span> </div> 

Я пытаюсь извлечь текст, содержащийся внутри этих тегов и использовать XPath «// текст) (» функция:

parser = etree.HTMLParser() 
tree = etree.parse(StringIO(html),parser) 
text = list(set(tree.xpath('//text()'))) 
text = " ".join(text) 

Он отлично работает, за исключением того, что я хотел бы изменить порядок извлечения. В настоящий момент я получаю следующий результат:

Содержание главы N1. Содержание главы N2. Глава 2. Глава 1.

Но я хотел бы получить результат как:

Глава 1. Содержание Глава 1. Глава 2. Содержание Глава 2.

ли есть ли лучший способ сделать это, кроме рекурсивной обработки каждого тега сверху документа?

ответ

1

Вы уверены, что string(/) не даст вам ответ, который вы хотите? Это не совсем то же самое, что и у вас, потому что для документа <p><i>Hello</i>!</p> он даст вам "Hello!", а не "Hello !", но в большинстве случаев я бы подумал, что это то, что вы хотите.

+0

Я еще не тестировал «string (/)», но мне нужно сохранить правильное разделение слов в моем результирующем тексте. Насколько я понимаю ваш подход, у меня будут проблемы с этим. Поэтому обработка моего примера вернет «Глава 1. Содержание главы 1. Глава 2. Контракты главы 2.». Это будет проблемой. – Termos

+1

Это зависит от вашей разметки. Если вы используете смешанный контент обычным способом, то мой подход прав, а ваш неверный - вы добавите дополнительные пробелы, где это не подходит. С другой стороны, если вы хотите добавить пробелы везде, где есть граница элемента, ваш подход будет лучше. –

+0

Майкл, я закончил тем, что использовал ваш подход. Я только модифицировал алгоритм для замены тегов
разделителем, содержащим пробел. Без этой модификации я бы получил «Helloworld!». от '

Hello
world!
', что я не ожидал. Кстати, мне пришлось использовать замену регулярных выражений в исходном html до создания дерева lxml, потому что я не мог нормально работать с функцией lxml replace(). – Termos

0

Похоже, вы пытаетесь использовать set для удаления дубликатов.

В python элементы в set неупорядочены, это означает, что порядок, в котором вы получаете элементы из набора, зависит от реализации, поэтому вы не можете использовать этот метод удаления дубликатов, если вы хотите сохранить заказ ,

text = " ".join(tree.xpath("//text()")) 

Будет производить ожидаемый результат в вашем случае, если нет дубликатов.

+0

спасибо. Вы правы, хотя вопрос был о Xpath :) – Termos

Смежные вопросы