文章目录
- CSS selector
- Xpath
- 正则表达式
- 选择元素方法的具体应用
右键检查的element板块下按Ctrl-F,可以输入css selector或xpath来定位元素
当然也要注意“所见非所得”和元素绝对位置改变的情况
CSS selector
- 根据Tag标签选择:Tag标签名
(Tag标签通配符:*) - 根据id选择:#id名
- 根据class选择:.class名(当class名有空格时,空格都换成“.”)
- 根据其他属性选择:[属性名] 或 [属性名=属性值]
- 子节点:父节点特征 > 子节点特征
(选择的是子节点,父节点是用来限制范围的) - 后代节点:祖节点 后代元素
(子节点与后代节点的区别是,子节点是下一级的,但后代可以是下一级,也可以是下下一级,只要包含在里面就可以) - 父节点的第n个子节点::nth-child(n)
- 父节点的倒数第n个子节点::nth-last-child(n)
- 父节点的第n个某类型的子节点:Tag标签名:nth-of-type(n)
- 父节点的倒数第n个某类型的子节点:Tag标签名:nth-last-of-type(n)
- 父节点的奇数节点::nth-child(even)
- 父节点的偶数节点::nth-child(odd)
- 相邻兄弟节点:“兄”元素特征+“弟”元素特征
- 所有兄弟节点:“兄”元素特征~“弟”元素特征
- 满足特征1或特征2:特征1,特征2
(注意,逗号的优先级是最低的,也就是可以把逗号两边各看成一个整体)
Xpath
- 根据属性选择:
属性名:[@属性名]
属性名及属性值:[@属性名=‘属性值’]
(class名有空格也不慌,原封不动复制过去就可以了)
属性值包含某字符串:[contains(@属性名,某字符串)]
属性值以某字符串开头:[starts-with(@属性名,某字符串)]
属性值以某字符串结尾:[ends-with(@属性名,某字符串)]
(但是这是xpath 2.0 的语法 ,目前浏览器都不支持) - 子节点:/隔开
类似于文件路径,一般以/html/开头
(Tag标签通配符:*) - 后代节点://隔开
//开头相当于是在所有当中找 - 父节点的第n个子节点:*[n]
- 父节点的第n个某类型子节点:Tag标签名[n]
- 父节点的第n个子节点:*[last()-(n-1)]
- 父节点的第n个某类型的子节点:Tag标签名[last()-(n-1)]
- 父节点的某范围的子节点:
*[position() <= n]
*[position() < n]
*[position() >= last()-2] - 父节点:/…
- 在某元素内部再用xpath选择元素:./开头
- 所有兄弟节点:following-sibling::
- 满足特征1或特征2:特征1 | 特征2
正则表达式
正则表达式
re.S:匹配换行符
re.I:不区分大小写
最常用——惰性匹配(.*?) 可以解决大多数问题了
import re
from bs4 import BeautifulSoup
soup = BeautifulSoup(response.text, 'html.parser')
result = soup.find_all(re.compile('h.*?o', re.S | re.I)) # 保留共有的有区分度的特征,把中间部分用.*?代替
选择元素方法的具体应用
一个网页由三部分组成:html搭建网页框架,css渲染网页样式,JavaScript完成脚本指令
如果网页中含有Ajax请求(网页url不变,但可以刷新数据),这是典型的前后端分离的技术,刷新机制是后台发送json格式的数据包
对于网页前端展现的信息,我们一般直接爬取html来解析里面的数据,css与样式有关是不需要爬取的,JavaScript有一些情况下需要爬取(通常含有不规范的json)
html中的数据我们通常采用BeautifulSoup的html.parser解析器来解析,通过select方法,输入css selector语法就可以完成定位
对于一些绝对路径固定的板块,我们也可以直接copy它的xpath,用lxml的etree来解析,通过xpath方法,将xpath路径粘贴过来就可以完成定位
json格式的后台数据包,我们直接用json库将其转换成字典类型,再从中获取想要的数据
特殊情况下,我们可能需要JavaScript中的一些数据,这种情况下我们同样用BeautifulSoup的html.parser解析器来解析html源码,通过find_all方法,引入正则表达式进行定位