Нахождение html-элемента с помощью класса с использованием lxml - PullRequest
11 голосов
/ 22 ноября 2011

Я искал везде и больше всего нашел doc.xpath ('// element [@ class = "classname"]'), но это не работает, что бы я ни пытался.

код, который я использую

import lxml.html

def check():
    data = urlopen('url').read();
    return str(data);

doc = lxml.html.document_fromstring(check())
el = doc.xpath("//div[@class='test']")
print(el)

Он просто печатает пустой список.

Edit: Как странно. Я использовал Google в качестве тестовой страницы, и там он работает нормально, но он не работает на странице, которую я использовал (youtube)

Вот точный код, который я использую.

import lxml.html
from urllib.request import urlopen
import sys

def check():
    data = urlopen('http://www.youtube.com/user/TopGear').read(); #TopGear as a test
    return data.decode('utf-8', 'ignore');


doc = lxml.html.document_fromstring(check())
el = doc.xpath("//div[@class='channel']")
print(el)

Ответы [ 3 ]

24 голосов
/ 24 ноября 2011

На странице TopGear, которую вы используете для тестирования, нет элементов <div class="channel">. Но это работает (например):

el = doc.xpath("//div[@class='channel-title-container']")

Или это:

el = doc.xpath("//div[@class='a yb xr']")

Чтобы найти <div> элементов с атрибутом class, которые содержат строку channel, можно использовать

el = doc.xpath("//div[contains(@class, 'channel')]") 
1 голос
/ 28 апреля 2019

HTML использует классы (много), что делает их удобными для перехвата запросов XPath.Однако XPath не знает и не поддерживает классы CSS (или даже разделенные пробелами списки), что делает проверку задниц болью в проверке: канонически правильный способ поиска элементов, имеющих определенный класс:

//*[contains(concat(' ', normalize-space(@class), ' '), '$className')]

В вашем случае это

el = doc.xpath(
    "//div[contains(concat(' ', normalize-space(@class), ' '), 'channel')]"
)
# print(el)
# [<Element div at 0x7fa44e31ccc8>, <Element div at 0x7fa44e31c278>, <Element div at 0x7fa44e31cdb8>]

или используйте собственную функцию XPath hasclass (* классы)

def _hasaclass(context, *cls):
    return "your implementation ..." 

xpath_utils = etree.FunctionNamespace(None)
xpath_utils['hasaclass'] = _hasaclass

el = doc.xpath("//div[hasaclass('channel')]")
1 голос
/ 26 января 2012

Вы можете использовать lxml.cssselect для упрощения запроса class и id: http://lxml.de/dev/cssselect.html

...