Как получить доступ к встроенному элементу внутри цикла в lxml? - PullRequest
0 голосов
/ 12 февраля 2012

Я пытаюсь отсканировать значения с веб-сайта.

# get the raw HTML
fruitsWebsite = lxml.html.parse( "http://pagetoscrape.com/data.html" )

# get all divs with class fruit 
fruits = fruitsWebsite.xpath( '//div[@class="fruit"]' )

# Print the name of this fruit (obtained from an <em> in the fruit div)
for fruit in fruits:
    print fruit.xpath('//li[@class="fruit"]/em')[0].text

Однако интерпретатор Python жалуется, что 0 - итератор за пределами допустимых границ.Это интересно, потому что я уверен, что этот элемент существует.Как правильно получить доступ к внутреннему элементу <em> с помощью lxml?

1 Ответ

2 голосов
/ 12 февраля 2012

Следующий код работает для меня с моим тестовым файлом.

#test.py
import lxml.html

# get the raw HTML
fruitsWebsite = lxml.html.parse('test.html')

# get all divs with class fruit 
fruits = fruitsWebsite.xpath('//div[@class="fruit"]')

# Print the name of this fruit (obtained from an <em> in the fruit div)
for fruit in fruits:
    #Use a relative path so we don't find ALL of the li/em elements several times. Note the .//
    for item in fruit.xpath('.//li[@class="fruit"]/em'):
        print(item.text)


#Alternatively
for item in fruit.xpath('//div[@class="fruit"]//li[@class="fruit"]/em'):
    print(item.text)

Вот HTML-файл, который я использовал для повторного тестирования. Если это не работает для html, который вы тестируете снова, вам нужно будет опубликовать пример файла, который не работает, как я и просил в комментариях выше.

<html>
<body>
Blah blah
<div>Ignore me</div>
<div>Outer stuff
    <div class='fruit'>Some <em>FRUITY</em> stuff.
    <ol>
        <li class='fruit'><em>This</em> should show</li>
        <li><em>Super</em> Ignored LI</li>
        <li class='fruit'><em>Rawr</em> Hear it roar.</li>
    </ol>
    </div>
</div>
<div class='fruit'><em>Super</em> fruity website of awesome</div>
</body>
</html>

Вы определенно получите слишком много результатов с кодом, который вы первоначально разместили (внутренний цикл будет искать все дерево, а не поддерево для каждого "фрукта"). Ошибка, которую вы описываете, не имеет большого смысла, если ваш вклад отличается от того, что я понял.

...