分析HTML代码,作者目前喜欢利用正则表达式和XPATH
常用的工具
- 正则表达式
- XPATH
- beautiful soup
正则表达式
十分强大的工具, 一定要学会的东西
推荐一个练习正则表达式的网站
练习网站
XPATH
首先你需要安装 lxml 包
lxml库是一种专门分析xml文件的包
from lxml import etree
tree = etree.parse("t.xml")
相关操作
tree.getroot()
root.tag
root.getchildren()
# 返回的数据类型都是N维列表,你可以用索引访问的
root.get('id') # 获得属性
root.text # 获得文本内容
操作HTML
# 从文件
from lxml import etree
tree = etree.parse("t.html", etree.HTMLParser())
# 从代码
tree = etree.HTML(ele)
Xpath有其专门的语法,(懂操作系统的文件路径嘛??懂?那XPATH语法对你来说就简单不少了)
语法规则 | 作用 |
---|---|
nodename | 选取此节点的所有子节点 |
/ | 从此节点选取直接子节点 |
// | 从此节点选取子孙节点 |
. | 当前节点 |
. . | 父节点 |
@ | 选取属性 |
(直接进行有关属性操作的举例)
html.xpath('//a[@href=""]')
# 选取每个a节点,要求a节点的href=""
html.xpath('//a[contains(@href, "www")]/@href')
# 选取每个a节点,要求a节点的href属性包含www, 并获取其href
多属性匹配(and or)
html.xpath('//a[@href = "" and @href = ""]')
html.xpath('//a[contains(@href, "www") or ../@value="1234"]')
按序查找
html.xpath('//a[1]/@href')
# 获取第一个a节点的href
html.xpath('//a[position() = 2]/text()')
# 获取第二个a节点的文本
对了,xpath返回的也是n维列表,列表的操作都懂的
节点选择器
Xpath也有相应的选择器来更精准的选择节点
轴名称 | 作用 |
---|---|
ancestor | 选择当前节点的所有先辈 |
ancestor-or-self | 选择当前节点的所有先辈以及自己 |
attribute | 选择当前节点的所有属性 |
parent | 选择当前节点的父节点 |
child | 选择当前节点的所有子节点 |
descendant | 选择当前节点的所有子孙节点 |
descendant-or-self | 选择当前节点的所有子孙节点以及自己 |
following | 选取文档中当前节点的结束标签之后的所有节点 |
following-sibling | 选取当前节点之后的所有兄弟节点(选择兄弟节点) |
preceding | 选取当前节点开始标签之前的所有节点 |
preceding-sibling | 选择当前节点之前的所有兄弟节点 |
self | 选取自己 |
namespace | 选取当前节点的命名空间的节点(我也不会用) |
提示:Chrome可以自动获取xpath路径(所以你几乎不用自己写)
Beautiful Soup
- 解析器
解析器 | 写法 | 功能 |
---|---|---|
Python自带解析器 | BeattifulSoup(html, ‘html.parser’) | python自带,速度适中,容错能力强 |
lxml HTML解析器 | BeautifulSoup(html, ‘lxml’) | 速度快,容错能力强,需要C语言支持 |
lxml XML 解析器 | BeautifulSoup(html, ‘xml’) | 速度快,支持xml,需要C语言支持 |
html5lib解析器 | BeautifulSoup(html, ‘html5lib’) | 最好的容错性,已浏览器的方式解析文档,生成Html5格式的文档,速度慢 |
- 节点选择器
2.1 节点选择
soup.li.name # 第一个li节点的名字
soup.li.attrs # 第一个li节点的属性 -> dict
soup.li.attrs['class'] # 第一个li节点的class属性
soup.li.string # 第一个li节点的内容
2.2 嵌套节点选择
soup.body.div.ul.li.a.string
2.3 子节点选择
soup.body.div.children # 子节点地址 需要自己for手动遍历
soup.body.div.contents # 子节点列表
soup.body.div.descendants # 子孙节点 需要自己for遍历
2.4 父节点选择
soup.body.div.parent # 父节点
soup.body.div.parent['class'] #
- 方法选择器
3.1 find_all
函数参数:name, attrs,text
其中name用于指定节点名称,
soup.find_all(name='ul') # --> list
attrs用于表示节点属性 attrs={‘id’:'button'}
soup.find_all(attrs={'id':'button'})
text匹配文本节点,可以是正则表达式
soup.find_all(text='geekori.com');
soup.find_all(text=re.compile('hello'))
3.2 find
与find_all类似,但是find只返回所查找到的第一个结果
- CSS选择器
如果你学习过CSS,这个东西你已经会了
常用css选择器
名称 | 功能 |
---|---|
.classname | 选取class属性为classname的节点 |
nodename | 选取节点为nodename的节点 |
#idname | 选取id为idname的节点 |
soup.select('.item') # --> list
soup.select('#button1')
soup.select('li')
提示:Chrome可以自动获取CSS路径