Подтвердить что ты не робот

Получите текст второго элемента с XPath?

<span class='python'>
  <a>google</a>
  <a>chrome</a>
</span>

Я хочу получить chrome и работать с этим уже.

q = item.findall('.//span[@class="python"]//a')
t = q[1].text # first element = 0

Я хотел бы объединить его в одно выражение XPath и просто получить один элемент вместо списка.
Я пробовал это, но он не работает.

t = item.findtext('.//span[@class="python"]//a[2]') # first element = 1

И фактический, а не упрощенный HTML-код выглядит следующим образом.

<span class='python'>
  <span>
    <span>
      <img></img>
      <a>google</a>
    </span>
    <a>chrome</a>
  </span>
</span>
4b9b3361

Ответ 1

Я пробовал это, но он не работает.

t = item.findtext('.//span[@class="python"]//a[2]')

Это часто задаваемый вопрос об аббревиатуре //.

.//a[2] означает: выберите все a потомки текущего node, которые являются вторым дочерним элементом a их родителя. Таким образом, это может выбрать более одного элемента или никакого элемента - в зависимости от конкретного XML-документа.

Проще говоря, оператор [] имеет более высокий приоритет, чем //.

Если вы хотите, чтобы только один (второй) из всех возвращенных узлов, вы должны использовать скобки для принудительного выбора:

(.//a)[2]

Это действительно выбирает второй a потомок текущего node.

Для фактического выражения, используемого в вопросе, измените его на:

(.//span[@class="python"]//a)[2]

или изменить его на:

(.//span[@class="python"]//a)[2]/text()

Ответ 2

Я не уверен, в чем проблема...

>>> d = """<span class='python'>
...   <a>google</a>
...   <a>chrome</a>
... </span>"""
>>> from lxml import etree
>>> d = etree.HTML(d)
>>> d.xpath('.//span[@class="python"]/a[2]/text()')
['chrome']
>>>

Ответ 3

От комментариев:

или упрощение фактического HTML, который я опубликовал, слишком прост.

Вы правы. В чем смысл .//span[@class="python"]//a[2]? Это будет расширено:

self::node()
 /descendant-or-self::node()
  /child::span[attribute::class="python"]
   /descendant-or-self::node()
    /child::a[position()=2]

Окончательно выберите второй a child (fn:position() относится к тону child). Таким образом, ничто не будет выбрано, если ваш документ похож:

<span class='python'> 
  <span> 
    <span> 
      <img></img> 
      <a>google</a><!-- This is the first "a" child of its parent --> 
    </span> 
    <a>chrome</a><!-- This is also the first "a" child of its parent --> 
  </span> 
</span> 

Если вы хотите второго из потомков, используйте:

descendant::span[@class="python"]/descendant::a[2]