Class 使用lxml查找带有类的html元素

Class 使用lxml查找带有类的html元素,class,python-3.x,lxml,Class,Python 3.x,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

我到处都搜索过,找到最多的是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)
它只是打印一个空列表

编辑: 真奇怪。我使用谷歌作为测试页面,它在那里运行良好,但在我使用的页面(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)

用于测试的TopGear页面没有任何
元素。但这是可行的(例如):

或者这个:

el = doc.xpath("//div[@class='a yb xr']")
要查找具有包含字符串
频道
属性的
元素,可以使用

el = doc.xpath("//div[contains(@class, 'channel')]") 

您可以使用lxml.cssselect来简化
class
id
请求:

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>]

“url”
是一个3个字符的字符串。这不是一个HTML文件。显然我没有发布真正的url,而是这样做了。请提供一个。
品牌页面频道
频道
不同。但是,根据css,该元素有两个类,品牌页面和频道。那么为什么不呢?是的,根据CSS有两个类。但是XPath不知道CSS的规则。对于XPath,
品牌页面频道
只是一个没有特殊意义的字符串。这实际上很有用,谢谢。作为一个测试,我试图在这个页面上获取一个元素,但它也不起作用。这真的开始让我生气了。el=doc.xpath('//a[@class=“vote accepted off”]')它似乎不喜欢找到没有子元素的元素。为了完成您的回答,我们还可以使用not()进行否定。例如:
el=doc.xpath(//div[contains(@class,'channel'))和not(contains(@class,'disabled'))])
中的第二个参数包含()还应添加空格(如
'$className'
'channel'
)。否则您仍将匹配类,如
somechannel
el = doc.xpath(
    "//div[contains(concat(' ', normalize-space(@class), ' '), 'channel')]"
)
# print(el)
# [<Element div at 0x7fa44e31ccc8>, <Element div at 0x7fa44e31c278>, <Element div at 0x7fa44e31cdb8>]
def _hasaclass(context, *cls):
    return "your implementation ..." 

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

el = doc.xpath("//div[hasaclass('channel')]")