Поиск элемента html с классом с помощью lxml

Я искал всюду, и я больше всего нашел 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)

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

Изменить: Как странно. Я использовал 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)

Ответ 1

На странице 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')]") 

Ответ 3

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')]")