С lxml.html как мне получить доступ к отдельным элементам без использования цикла for?

Это HTML:

<tr class="headlineRow">
  <td>
    <span class="headline">This is some awesome text</span>
  </td>
</tr>

Например, это не удастся с IndexError:

 for row in doc.cssselect('tr.headlineRow'):
     headline = row.cssselect('td span.headline')
     print headline[0]

Это пройдет:

 for row in doc.cssselect('tr.headlineRow'):
     headline = row.cssselect('td span.headline')
     for first_thing in headline:
         print headline[0].text_content()
0
Lionel 26 Авг 2010 в 10:53

4 ответа

Лучший ответ

Я опробовал ваш пример, используя CSSSelector и headline[0], которые работали нормально. См. ниже:

>>> html  ="""<tr class="headlineRow">
  <td>
    <span class="headline">This is some awesome text</span>
  </td>
</tr>"""
>>> from lxml import etree
>>> from lxml.cssselect import CSSSelector
>>> doc = etree.fromstring(html)
>>> sel1 = CSSSelector('tr.headlineRow')
>>> sel2 = CSSSelector('td span.headline')
>>> for row in sel1(doc):
    headline = sel2(row)
    print headline[0]

<Element span at 8f31e3c>
0
Manoj Govindan 26 Авг 2010 в 07:08

Я обычно использую метод xpath для таких вещей. Возвращает список совпадающих элементов.

>>> spans = doc.xpath('//tr[@class="headlineRow"]/td/span[@class="headline"]')
>>> spans[0].text
'This is some awesome text'
1
snapshoe 20 Сен 2010 в 06:14

Ваш "провальный" пример отлично работает для меня? Либо вы ошиблись, когда пытались это сделать, либо вы используете более старую версию lxml, в которой есть - теперь исправленная - ошибка (я пробовал 2.2.6, а с 2.1.1 - самую старую из всех, что у меня были, и обе работали)

0
Steven 26 Авг 2010 в 09:02

Доступ к элементам осуществляется так же, как и к вложенным спискам:

>>> doc[0][0]
<Element span at ...>

Или через селекторы CSS:

doc.cssselect('td span.headline')[0]
0
Tim McNamara 28 Авг 2010 в 04:54