高埗网站仿做,江西赣州,个人怎么申请域名,手机网站开发屏幕尺寸一般是多少python简单易懂的lxml读取HTML节点及常用操作方法
1. 初始化和基本概念
lxml 是一个强大的pyth库#xff0c;用于处理XML和HTML文档。它提供了类似BeautifulSoup的功能#xff0c;但性能更高。在使用lxml时#xff0c;通常会先解析HTML或XML文档#xff0c;得到一个Eleme…python简单易懂的lxml读取HTML节点及常用操作方法
1. 初始化和基本概念
lxml 是一个强大的pyth库用于处理XML和HTML文档。它提供了类似BeautifulSoup的功能但性能更高。在使用lxml时通常会先解析HTML或XML文档得到一个ElementTree对象。
pip install lxml2. 解析HTML文档 使用lxml.html.fromstring(html)来从字符串中创建一个ElementTree对象。 示例 from lxml import html
html_content htmlbodypHello world!/p/body/html
tree html.fromstring(html_content)或者使用etree.HTML(rhtml_content)来创建ElementTree对象
from lxml import etree
html_content htmlbodypHello world!/p/body/html
tree etree.HTML(html_content)3. XPath选择器 XPath是一种用于在XML文档中查找信息的语言。 lxml支持XPath选择器可以用来定位文档中的元素。 示例 # 获取所有的段落标签
paragraphs tree.xpath(//p)4. 遍历节点 iter_node() 函数可以用来遍历一个节点的所有子节点。 示例 for node in iter_node(body):# 处理每个节点pass5. 获取节点属性 使用.attrib属性来获取节点的所有属性。 示例 class_name node.attrib.get(class, )在使用lxml处理HTML或XML文档时获取节点的属性和属性值是非常常见的需求。下面详细解释如何获取标签的全部属性以及如何分别获取单个属性和属性值。
1. 获取标签的全部属性
在lxml中你可以通过访问节点的attrib属性来获取所有属性。attrib是一个字典键是属性名值是属性值。
示例代码
from lxml import htmlhtml_content
div idcontent classmain-contentpHello, world!/p
/div
tree html.fromstring(html_content)
div_node tree.xpath(//div)[0]# 获取所有属性
all_attributes div_node.attrib
print(All attributes:, all_attributes)# 输出
# All attributes: {id: content, class: main-content}2. 分别获取单个属性和属性值
如果你只需要获取某个特定属性的值可以直接通过键访问字典中的值。如果属性不存在则可以使用get方法提供一个默认值。
示例代码
# 获取单个属性
id_attribute div_node.attrib.get(id, default-id)
print(ID attribute:, id_attribute)class_attribute div_node.attrib.get(class, default-class)
print(Class attribute:, class_attribute)# 输出
# ID attribute: content
# Class attribute: main-content3. 获取属性值
如果属性名已知可以直接通过键访问字典中的值。如果属性名未知或需要处理多个属性可以遍历attrib字典来获取所有属性及其值。
示例代码
# 遍历所有属性
for attr_name, attr_value in div_node.attrib.items():print(fAttribute: {attr_name}, Value: {attr_value})# 输出
# Attribute: id, Value: content
# Attribute: class, Value: main-content4. 处理特殊情况
在某些情况下属性可能包含空格分隔的多个值例如class属性这时你可以使用split方法来分割字符串。
示例代码
# 处理包含多个值的属性
class_values div_node.attrib.get(class, ).split()
print(Class values:, class_values)# 输出
# Class values: [main-content]5. 综合示例
下面是一个综合示例展示了如何获取节点的所有属性、单个属性以及如何处理特殊情况下的属性值。
from lxml import htmlhtml_content
div idcontent classmain-content secondarypHello, world!/p
/div
tree html.fromstring(html_content)
div_node tree.xpath(//div)[0]# 获取所有属性
all_attributes div_node.attrib
print(All attributes:, all_attributes)# 获取单个属性
id_attribute div_node.attrib.get(id, default-id)
print(ID attribute:, id_attribute)class_attribute div_node.attrib.get(class, default-class)
print(Class attribute:, class_attribute)# 遍历所有属性
for attr_name, attr_value in div_node.attrib.items():print(fAttribute: {attr_name}, Value: {attr_value})# 处理包含多个值的属性
class_values div_node.attrib.get(class, ).split()
print(Class values:, class_values)# 输出
# All attributes: {id: content, class: main-content secondary}
# ID attribute: content
# Class attribute: main-content secondary
# Attribute: id, Value: content
# Attribute: class, Value: main-content secondary
# Class values: [main-content, secondary]6. 获取节点文本 使用.text属性来获取节点的文本内容。 示例 node_text node.text或者如果下面还有子节点的话最好是用
# 将所有的文本拼接起来
link_name .join(child.itertext()).strip().replace(\n, ).strip()
# 去掉过多的空格
link_name re.sub(r\s, , link_name ).strip()7. 获取节点路径 使用.getroottree().getpath(node)来获取节点的完整XPath路径。 示例 path node.getroottree().getpath(node)1.获取最末尾节点路径 # 提取最后一个 / 后面的元素last_element path.split(/)[-1] if / in path else path8. 检查节点类型(标签名) 通过.tag属性来检查节点的标签名。 示例 if node.tag p:# 处理段落节点pass9. 子节点操作 使用.getchildren()来获取节点的所有子节点node.getparent()获取节点的所有父节点。 示例 children node.getchildren()10. 提取属性值 使用属性名来提取属性值。 示例 image_srcs node.xpath(.//img/src)11. 节点转换为字符串HTML 使用etree.tostring(node)来将节点转换为字符串形式。 示例 node_html etree.tostring(node, pretty_printTrue, encodingunicode)12. 计算文本密度 文本密度是指文本相对于其他非文本内容如图片、链接的比例。 通过计算节点中的文本长度与节点总长度的比例来估算文本密度。 示例 text_density len(node.text_content()) / len(etree.tostring(node))13. 处理列表页面 在处理列表页面时有时候需要检查是否有特定的类名来进行对应操作如list。 示例 if list in a_element[0].get(class, ).lower():# 处理列表节点pass扩展
构建包含属性的XPath路径
流程:
1. 获取子节点的XPath路径
首先我们遍历一个节点的所有子节点并获取每个子节点的XPath路径。
for child in node.getchildren():xpath_path / node.getroottree().getpath(child)2. 获取子节点的所有属性
对于每个子节点我们获取其所有属性
attributes child.attrib3. 构建包含属性的XPath路径
接下来我们根据子节点的属性构建一个完整的XPath路径。如果子节点有属性我们会在XPath路径后面加上属性条件。
3.1 属性存在时
如果子节点有属性我们构建一个包含所有属性的XPath路径
if attributes:xpath_with_attributes xpath_path [for i, (key, value) in enumerate(attributes.items()):xpath_with_attributes f{key}{value}if i len(attributes) - 1:xpath_with_attributes and xpath_with_attributes ]attributes.items() 返回一个迭代器其中包含了属性的键值对。enumerate(attributes.items()) 为每个属性分配一个索引。f{key}{value} 构建一个XPath条件表示属性 key 的值为 value。如果不是最后一个属性则添加 and 以连接多个条件。最后添加 ] 来结束XPath条件。
3.2 属性不存在时
如果子节点没有属性我们直接使用原始的XPath路径
else:xpath_with_attributes xpath_path综合示例
下面是一个完整的示例代码展示了如何遍历节点的子节点并构建包含属性的XPath路径
from lxml import htmlhtml_content
htmlbodydiv idcontainer classmainpHello, world!/pa href/link idexampleExample Link/a/div/body
/html
tree html.fromstring(html_content)
root_node tree.xpath(//div[idcontainer])[0]# 遍历根节点的所有子节点
for child in root_node.getchildren():xpath_path / root_node.getroottree().getpath(child)# 获取子节点的所有属性attributes child.attrib# 构建包含所有属性的XPath路径if attributes:xpath_with_attributes xpath_path [for i, (key, value) in enumerate(attributes.items()):xpath_with_attributes f{key}{value}if i len(attributes) - 1:xpath_with_attributes and xpath_with_attributes ]else:xpath_with_attributes xpath_pathprint(fXPath Path: {xpath_path})print(fXPath with Attributes: {xpath_with_attributes})print(Attributes:, attributes)print()# 输出
# XPath Path: /html/body/div/p
# XPath with Attributes: /html/body/div/p
# Attributes: {}
#
# XPath Path: /html/body/div/a
# XPath with Attributes: /html/body/div/a[href/link and idexample]
# Attributes: {href: /link, id: example}详细解释 获取子节点的XPath路径 node.getchildren() 返回节点的所有子节点。node.getroottree().getpath(child) 获取子节点的XPath路径。我们在路径前加上 / 来确保路径格式正确。 获取子节点的所有属性 child.attrib 返回子节点的所有属性及其值。 构建包含属性的XPath路径 如果子节点有属性我们构建一个包含所有属性的XPath路径。使用 enumerate 来为每个属性分配一个索引以便在多个属性之间添加 and。如果子节点没有属性我们直接使用原始的XPath路径。