我们给出一段测试用的HTML代码.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Title</title>
</head>
<body>
<div>
<p>一个很厉害的人</p>
<ol>
<li id="10086">周大强</li>
<li id="10010">周芷若</li>
<li class="joy">周杰伦</li>
<li class="jolin">蔡依林</li>
<ol>
<li>阿信</li>
<li>信</li>
<li>信不信</li>
</ol>
</ol>
</div>
<hr />
<ul>
<li><a href="http://www.baidu.com">百度</a></li>
<li><a href="http://www.google.com">谷歌</a></li>
<li><a href="http://www.sogou.com">搜狗</a></li>
</ul>
<ol>
<li><a href="feiji">飞机</a></li>
<li><a href="dapao">大炮</a></li>
<li><a href="huoche">火车</a></li>
</ol>
<div class="job">李嘉诚</div>
<div class="common">胡辣汤</div>
</body>
</html>
xpath
上半场
from lxml import etree
# 加载HTML
f = open("xpath测试.html", mode='r', encoding='utf-8')
page_source = f.read()
# 和bs4一样, 把HTML交给etree
hm = etree.HTML(page_source) # type:etree._Element
# xpath各种用法
# 节点: 每个HTML标签叫节点
# 最外层节点: 根节点
# 内层节点: 子节点
# 父子节点: <爹><子></子></爹>
html = hm.xpath("/html") # /根
print(html) # 看一眼标签名(测试用, 不用记住)
body = hm.xpath("/html/body") # 第二个/表示子节点
print(body)
# 接下来这句话请记住, xpath提取到的内容不论多少, 都会返回列表
p = hm.xpath("/html/body/div/p/text()") # 想要p里面的文本
print(p) # 列表
print(p[0]) # 要么取0.
print("".join(p)) # 要么用join()进行合并.
# 如果页面结构非常复杂. 这样一层一层数下来. 过年了
# xpath我们还可以用相对定位
p = hm.xpath("//p/text()") # // 表示在页面任意位置找
print(p) # 依然有效
# 我想找到 `周大强`, `周芷若`,`周杰伦`,`周大强`,`蔡依林`
li = hm.xpath("//div/ol/li/text()")
print(li)
# 我想找到 `一个很厉害的人`后面ol中所有的文本
li = hm.xpath("//div/ol//text()") # 第二个//表示所有
# 请注意. 这里多了很多空白,一般我们提取一篇文章的时候,会用这种.
# 结合字符串各种操作. 这些东西应该难不倒各位.
print(li)
print("".join(li).replace(" ", "").replace("\n", ""))
xpath
下半场(重点)
from lxml import etree
# 加载HTML
f = open("xpath测试.html", mode='r', encoding='utf-8')
page_source = f.read()
# 和bs4一样, 把HTML交给etree
hm = etree.HTML(page_source) # type:etree._Element
# 重点:根据位置数元素
# 我想要`周芷若`, 分析角度: 它是ol里第二个li
li = hm.xpath("//ol/li[2]/text()")
print(li) # 这里莫名其妙带出了`信`, 请思考为什么? 请思考怎么干掉`信`
# 我想单独找`信`聊聊
li = hm.xpath("//ol/ol/li[2]/text()")
print(li)
# 重点:根据属性筛选元素
# 我想要id=10086的li标签中的内容0
li = hm.xpath("//li[@id='10086']/text()")
print(li)
# 我想要class是joy的内容
li = hm.xpath("//*[@class='joy']/text()")
print(li)
# 我想要有class的li的内容
li = hm.xpath("//*[@class]/text()")
print(li)
# 我想和`啊信`,`信`,`信不信`单独聊聊
li_list = hm.xpath("//ol/ol/li")
for li in li_list:
print(li.xpath("./text()")) # ./表示当前节点, 也就是li
# 提取`百度`, 谷歌, 搜狗的超链接href属性
li_list = hm.xpath("//ul/li")
for li in li_list:
print(li.xpath("./a/text()")) # ./表示当前节点, 也就是li
print(li.xpath("./a/@href")) # @href 表示提取属性
# 我想要`火车`
li = hm.xpath("//body/ol/li[last()]/a/text()") # last() 拿到最后一个
print(li)
f.close()