Skip to content

Latest commit

 

History

History
437 lines (298 loc) · 7.82 KB

File metadata and controls

437 lines (298 loc) · 7.82 KB
Error in user YAML: (<unknown>): could not find expected ':' while scanning a simple key at line 3 column 1
---
- oeasy Python 0534
- 这是 oeasy 系统化 Python 教程,从基础一步步讲,扎实、完整、不跳步。愿意花时间学,就能真正学会。
本教程同步发布在: 

     个人网站: `https://oeasy.org` 
     蓝桥云课: `https://www.lanqiao.cn/courses/3584` 
     GitHub: `https://github.com/overmind1980/oeasy-python-tutorial` 
     Gitee: `https://gitee.com/overmind1980/oeasypython` 
---

语法 html 生成

回忆

  • 上次深入了 xpath
  • xpath
    • 用来筛选
    • xml 文件中的节点
表达式 描述
nodename 在当前位置选择此类节点
/ 从根节点选取 或 表示层级关系
// 在任意层级下的子孙路径下
. 选取当前节点
.. 选取当前节点的父节点
  • xpath 还有什么可以玩的呢?🤔

构造环境

  • 启动 本地Web服务
sudo service nginx start
sudo service nginx status
firefox http://localhost &
  • 浏览器

图片描述

  • 右键内容检查元素

复制xpath

  • 在 元素查看界面
    • 右键复制 - xpath

图片描述

  • 元素的xpath
    • 已经 复制到了 剪贴板

使用xpath

  • 在游乐场运行
import requests
from lxml import etree
response = requests.get("http://localhost")
b_html = response.content
et_html = etree.HTML(b_html)
nl = et_html.xpath("/html/body/p[1]")
print(nl)
  • /html/body/p[1]
    • /html
      • 根下的html下
    • /body
      • html下的body下
    • /p[1]
      • body 下的 第1个 p 元素

图片描述

  • 到底是 哪个段落(Paragraph)呢?

验证

图片描述

  • 查看文本
nl[0].text
  • 确认是 第一段

图片描述

  • 注意!!!

    • 元素树节点下标
      • 是从1开始
    • 与列表
      • 从0开始
  • 这里 用到的 中括号

    • 叫什么 方法 呢?

谓语 predicates

  • 谓词 predicates

图片描述

  • 如何理解谓词呢?

谓词

图片描述

  • 谓词
    • 是 对元素 进一步的描述
    • 是 筛选元素的 方式

图片描述

  • 中括号叫做谓词
    • 根据属性值筛选

任意元素

    • 代表任意元素
nl = et_html.xpath("//*")
for element in nl:
	print(element)
  • // 代表 任意层级
  • * 代表 任意元素
  • //* 代表 任意层级下的 任意元素

图片描述

  • 深度优先 遍历 所有元素

任意属性

  • 想筛选 所有 有属性的元素
nl = et_html.xpath("//*[@*]")
for element in nl:
	print(element)
  • 只有a元素 有属性href

图片描述

  • 想按照位置筛选

直接 搜索元素

  • nodelist
    • 这是 元素树节点的列表
    • list of element tree
nl = et_html.xpath("//a")
for element in nl:
	print(element)
  • 任意层级下的
    • a元素

图片描述

  • 找到
    • 2个a元素

图片描述

谓词筛选

nl = et_html.xpath("//a[@*]")
for element in nl:
	print(element)
  • //a[@*]
    • //a
      • 任意层级下的
      • a元素
    • [@*]
      • []是筛选谓词
      • @是attribute
      • *是任意的
      • 有任意属性的

图片描述

  • 想要 任意层级下
    • 有任意属性的
    • 任意元素

根据属性类型筛选

  • //a[@href]
    • //a
      • 任意层级下的
      • a元素
    • [@href]
      • 有@href属性的
nl = et_html.xpath("//a[@href]")
for element in nl:
	print(element)
  • 任意路径下
    • 有href属性的
    • a元素

图片描述

  • 想把其中一个a筛出来

观察网页

图片描述

nl = et_html.xpath("//a[@href=\"http://nginx.org/\"]")
for element in nl:
	print(element)
  • 注意 属性值 引用
    • 单引号或者双引号都可以
    • 冲突了的话 需要转义

图片描述

  • 像筛选 所有 有属性的a元素

双重谓词

  • 任意层级下的
    • 位置小于2的
    • 有href的a元素
nl = et_html.xpath("//a[1]")
for element in nl:
	print(element)
  • 以下xpath等价
表达式 描述
//a[1] 任意层级下 第一个 a元素
//a[postion()=1] 任意层级下 位置等于1的 a元素
//a[postion()<2] 任意层级下 位置小于2的 a元素

图片描述

  • xpath 可以
    • 成功得到元素列表
  • 但是
    • 可以得到 元素的属性 吗?

属性变量

et_html.
  • 到游乐场找找

图片描述

  • attrib 就是属性
    • 具体什么类型呢?

查看类型

et_html
et_html.attrib
  • 类型 是 字典

图片描述

  • 尝试遍历

遍历过程

  • "//a"
    • // 任意层级下的
nl = et_html.xpath("//a")
for ele in nl:
	print(ele.tag)
	print(ele.attrib)
  • 找到 任意层级下
    • 所有 有属性的元素
    • 打印他的属性字典

图片描述

  • 想要把超链接 都列出

列出超链接

nl = et_html.xpath("//a")
for ele in nl:
	print(ele.tag)
	print(ele.attrib["href"])
  • 可以用href
    • 索引到超链接

图片描述

  • 我们再温习一下下

尝试

  • 这里面出现了中括号[ ]
    • 找一下/html/body下
    • 第 1 个 p

图片描述

最后一个

  • /html/body/
    • 最后一个p元素

图片描述

  • 在索引运算符中使用了 last()
    • 此时last() = 3

倒数第二

  • 倒数第二个p

图片描述

  • 关键还是对 li 使用索引运算符
    • last()是最后一个
    • last() - 1 是倒数第二个

前两名 position

  • 前两个p

图片描述

  • p[position()<3]
    • 可以找到前两项
  • 如果我想找后两项呢?🤔

后两项

图片描述

  • p[position()>last()-2]
  • 可以找到后两项

存在href属性的a元素

  • 任意层级下href属性 的 a元素 🤪

图片描述

  • 可以试试href属性是特定值吗?

属性内容

图片描述

总结

  • 这次深入了 xpath 的筛选
    • 可以用中括号索引的方式对于子元素的位置进行筛选
xpath 表达式 含义
xpath("//p[1]") 第一个p
xpath("//p[last()]") 最后一个p
xpath("//p[position()<=3]") 正数前三个p
xpath("//p[position()>last()-2"]) 倒数两个p
  • 可以在索引中对属性进行筛选
    • @ 俗称花 a
    • 对应@ttribute
xpath 表达式 含义
//*[@href] 任意层级下
有href属性的
元素
//*[@href=\"http://nginx.org/"] 任意层级下
href属性是特定值的
元素
//a[last()][@href=\"http://nginx.org/"] 任意层级下
href属性是特定值的
最后一个
元素
//@ 任意层级下
任意属性
  • 还有什么好玩的呢?🤔
  • 下次再说

  • 本文来自 oeasy Python 系统教程。
  • 想完整、扎实学 Python,
  • 搜索 oeasy 即可。