Skip to content

Latest commit

 

History

History
282 lines (190 loc) · 6.91 KB

369-192577-lxml_元素_树形结构.sy.md

File metadata and controls

282 lines (190 loc) · 6.91 KB
show version enable_checker
step
1.0
true

lxml 元素 树形结构

回忆

  • 导入了 requests 模块
  • 完成了 http get 的过程
    • 发出了 request
    • 得到了 response
    • 状态码 200
  • 但是读到的内容是
    • 字节序列
    • 字符串序列
  • 如何解析 html 语言呢?🤔

分析

  • 想要解析 html
    • 那首先就要了解 html 语言的结构
  • html全称hyper-text markup language
    • 是一门 markup(标记性) 的语言
    • markup 是靠 html 标签元素 实现的

图片描述

  • 元素使用的 标签tag 包括
    • 开始标签
    • 结束标签
  • 标签是成对儿出现的

实例

图片描述

  • F12 可以检查元素
    • 也可以右键全部展开
    • 这就是一棵树
  • 一棵什么树?
    • 一棵 Dom 树

图片描述

  • 什么是 Dom 树呢?

Dom 树

  • Document Object Model
    • 文档对象模型

图片描述

  • 根节点在 html
    • html 长出两个分支
      • head
      • body
  • 然后各自底下还有子分支

渲染过程

图片描述

  • response 到达浏览器后
    • 首先需要分词 parse
    • 然后根据语义 semantic
    • 尝试生成一棵 dom 语义树
    • 然后再根据 css 样式表
    • 一步步地进行渲染成一个好看的页面

图片描述

  • 爬虫也需要渲染吗?

爬虫

  • 爬虫只看内容
    • 不需要渲染
    • 但也需要先生成 dom 树

图片描述

  • 怎么生成呢?
    • 尝试引入一个包

lxml

  • 这是目前分析 html 最好的包
    • lxml
    • 是第三方的包

图片描述

  • 第三方的包哪里查询帮助呢?

搜索

  • 在百度搜索lxml

图片描述

  • 这是一个开源的项目 lxml
    • http://lxml.de
      • github 的地址也指向这里
    • l 的意思是 library
    • xml 的意思就是 extensible markup language
  • 整体的意思就是一个能够简单地处理 xml 的 python 库

打开lxml.de

  • 他的特点是
    • 用 c 语言写了
      • 高效的 libxml2 和 libxslt 两个类库
      • 并封装成的 api
    • 使用 python 的简洁语法调用
    • 生成著名的 ElementTree

图片描述

  • 他可以解析 xml
    • 也就可以解析 html
    • 其实 html 是 xml 的一个子集
    • 毕竟都是 ml(Markup Language)
    • 都是树型结构

tutorial

  • 进入教程

图片描述

  • 本来想着是读取一个网页文件然后再生成树
    • 但是目前看起来的思路是
    • 在内存里直接通过调用函数生成树
    • 然后再处理这棵树
  • 树嘛
    • 首先要有树根节点

扎根

  • etree 的意思是
    • element tree
      • 元素树
    • 元素树树是由元素节点构成的

图片描述

  • 哪个元素是整棵树的根呢?

html元素

  • 获得节点的方式是
    • etree.Element("html")
    • 我们知道 html 元素 是网页文档的根
    • 这个 html元素的节点 是 我们所有其他元素的根
    • 也是我们从无到有生成这棵树的根

图片描述

  • 变量名是 et_html
    • et 代表他是 element tree 类型的
    • html 代表他是 html 根节点

图片描述

  • 先把根扎下之后
    • 需要开枝散叶

开枝

  • 可以为 html 元素节点
    • append 追加
      • body 子节点

图片描述

  • 可以追加出来

图片描述

  • 但是html节点和body节点的关系是什么呢?

建立层级

  • html 节点下
    • append body节点
    • 父子关系由 append 函数确定

图片描述

  • 在html元素节点上
    • 附加(append)了body子元素节点
    • 调用函数的是 html 元素节点,是父亲
    • 被调用的是 body 元素节点,是儿子
  • 所以我们看主动调用的意义是多么的重要啊!
    • 这样两个节点就建立了父子关系
  • 可以看看这父子关系吗?

输出父子关系

  • 我们可以把从无中生成的这棵树以字符串的方式输出
    • etree.tostring() 将etree节点输出为字节序列
      • 参数 pretty_print=True 参数控制层级的缩进表示
    • 将字节序列用 decode() 解码
      • 可以将字节序列解码为字符串

图片描述

  • 回忆一下:
    • encode 函数把字符串编码为字节序列
    • decode 函数把字节序列解码为字符串
    • 然后用 print()可以把这棵树解码出的字符串输出出来

图片描述

  • 这样我们不但给 html 元素追加了 body 元素
    • 而且输出了整棵树
  • 有追加就有删除

删除

  • append
    • 可以给节点添加子节点
  • remove
    • 可以给节点删除子节点

图片描述

  • 就当我 html 没有 body 你这个儿子

图片描述

  • 当然删了之后还可以再添加

再开支

  • 继续添加子节点
    • 这次添加两个子节点

图片描述

  • 添加新的子节点

图片描述

  • 再输出整棵树

再散叶

  • body 子节点里面有一个 ul

图片描述

  • 输出结果

图片描述

  • 不过 ul 里面有三个 li
  • 这怎么添加呢?

总结

  • 了解了 html 中的 dom 树
  • 树是由节点元素组成的
    • 节点元素可以用 etree.Element()得到
    • 最根本的元素是根元素
    • dom-tree 的根就是 html 元素
  • html 里面包括子节元素点
    • head
    • body
      • ul

图片描述

  • 重复的li元素怎么添加(append)呢?🤔
  • 下次再说