2013-04-29 2 views
4

У меня есть этот фрагмент кода HTMLlxml.html разбора с помощью XPath и переменных

<div id="dw__toc"> 
<h3 class="toggle">Table of Contents</h3> 
<div> 

<ul class="toc"> 
<li class="level1"><div class="li"><a href="#section">#</a></div> 
<ul class="toc"> 
<li class="level2"><div class="li"><a href="#link1">One</a></div></li> 
<li class="level2"><div class="li"><a href="#link2">Two</a></div></li> 
<li class="level2"><div class="li"><a href="#link3">Three</a></div></li> 

Теперь я хочу, чтобы разобрать его с lxml.html. В конце концов, я хочу функцию, где я могу обеспечить термин для поиска (т.е. «один») и функция должна возвращать

One 
#link1 

Сейчас я пытаюсь получить переменный в XPath.

Работы:

import lxml.html 
html = lxml.html.parse("www.myurl.com/slash/something") 

test=html.xpath("//ul[@class='toc']/li[@class='level2']/div[@class='li']/a/text()='One'") 

print test 

Попытка с переменной. Я хочу заменить hardcoded 'One' на переменную, которую я могу позже вернуться к функции.

Не работает:

import lxml.html 
html = lxml.html.parse("www.myurl.com/slash/something") 

desiredvars = ['One'] 
myresultset=((var, html.xpath("//ul[@class='toc']/li[@class='level2']/div[@class='li']/a[text()='%s']"%(var))[0]) for var in desiredvars) 

for each in myresultset: 
     print each 

Traceback (most recent call last): 
File "<stdin>", line 1, in <module> 
File "<stdin>", line 1, in <genexpr> 
IndexError: list index out of range 

Это основано на этот ответ: https://stackoverflow.com/a/10688235/2320453 Любая идея, почему это не работает? Это «правильный путь», чтобы сделать что-то подобное?

EDIT: Суммируя вещи: Я хочу искать в а-теги и получить текст из этого атрибуты, но я не хочу, полный список вместо этого я хочу, чтобы иметь возможность искать с Переменная. Псевдо-код:

import lxml.html 
html = lxml.html.parse("www.myurl.com/slash/something") 

searchterm = 'one' 

test=html.xpath("...a/text()=searchterm") 

print test 

Ожидаемый результат

One 
#link1 

ответ

4

Ваш первый пример ковшики, но, вероятно, не так, как вы думаете, что Шоуде:

test=html.xpath("//ul[@class='toc']/li[@class='level2']/div[@class='li']/a/text()='One'") 

Что это возвращает логический тип, который будет истинным, если условие ...='One' верно для любого из узлов в результирующем наборе в левой части выражения xpath. И вот почему вы получите ошибку во втором примере: True[0] недействителен.

Вы хотите, чтобы все узлы соответствовали исчислению, имея 'One' в виде текста. Соответствующее выражение будет:

test=html.xpath("//ul[@class='toc']/li[@class='level2']/div[@class='li']/a[text()='One']") 

Это возвращает набор узлов, как результат, или если вам просто нужен URL как строка:

test=html.xpath("//ul[@class='toc']/li[@class='level2']/div[@class='li']/a[text()='One']/@href") 
# returns: ['#link1'] 
+0

Спасибо! Вы правы, мой первый пример печатает 'True'. Ваш первый пример печатает элемент «Элемент» в 0xc99b90'. Как я могу привести его для печати 'One' и заменить' One' в '/ a [text() = 'One']' переменной? Я также отредактировал первый пост, в первую очередь испортил некоторые скобки. – duenni

+0

'text()' выбирает текстовый узел, поэтому '.../a/text()' yould возвращает список всех текстовых контуров всех якорей, если это то, что вам нужно, или вы можете использовать возвращаемый элемент для доступа его атрибуты из python. – mata

+0

Итак, лучше получить список со всеми элементами, а затем искать в этом списке из python вместо сужения выражения Xpath только для возврата одного элемента, который я ищу? – duenni

4

Я попытался ответ Mata, но для меня не работает :

div_name = 'foo' 
my_div = x.xpath(".//div[@id=%s]" %div_name)[0] 

Я нашел это на их сайте http://lxml.de/xpathxslt.html#the-xpath-method для тех, которые могли бы иметь такую ​​же проблему:

div_name = 'foo' 
my_div = x.xpath(".//div[@id=$name]", name=div_name)[0] 
+0

'my_div = x.xpath (" .// div [@id = '% s'] "% div_name) [0]' отлично работает – sebdelsol