Python(六十八)xpath案例实战
2022-02-27 本文已影响0人
Lonelyroots
07_xpath案例实战/01_xpath.py:
"""
pip install lxml
XPath常用规则:
nodename 选取此节点的所有子节点
/ 从当前节点选区直接子节点
// 从当前节点选取子孙节点
. 选取当前节点
.. 选取当前节点的父节点
@ 选取属性
xpath中索引是从1开始的
"""
from lxml import etree
str1 = """
<div>
<ul>
<li class="item-o"><a href="link1.html">first item</a></li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-inactive"><a href="link3.html"><span class="bold">third item</span></a</li>
<li class="item-1"><a href="link4. html">fourth item</a></li>
<li class="item-o"><a class="test" href="link5.html">fifth item</a></li>
</ul>
</div>
"""
tree = etree.HTML(str1)
# print(tree) # 打印<Element html at 0x1a5e1dfab48>
# print(type(tree)) # 打印<class 'lxml.etree._Element'>
# print(tree.xpath('//li')) # 打印所有li标签对象,[<Element li at 0x1e050626e88>, <Element li at 0x1e050626dc8>, <Element li at 0x1e050626ec8>, <Element li at 0x1e050626f08>, <Element li at 0x1e050626f48>]
# print(tree.xpath('//li/@class')) # 打印所有li下的class属性值,['item-o', 'item-1', 'item-inactive', 'item-1', 'item-o']
# print(tree.xpath('//li/a[@href="link1.html"]')) # 打印li标签下a的href为"link1.html"的a标签对象[<Element a at 0x258ffa14e08>]
# print(tree.xpath('//li//span')) # 因为/是获取子元素,如果多层则使用//。打印[<Element span at 0x162dacd6848>]
# print(tree.xpath('//li/a/@class')) # 打印['test']
# print(tree.xpath('//li/a//@class')) # 打印a标签自己和之下的所有class属性值['bold', 'test']
# print(tree.xpath('//li[last()]/a/@href')) # 打印最后一个li的a的href值['link5.html']
# print(tree.xpath('//li[last()-1]/a/@href')) # 打印倒二个li的a的href值['link4.html']
# print(tree.xpath('//li[1]/a/@href')) # xpath中索引是从1开始的,打印第一个li的a的href值['link1.html']
# print(tree.xpath('//li[1]/a/text()')) # 提取第一个li里的a标签内容,打印['first item'],text()取出内容
# result = tree.xpath('//li[1]/a')
# print(result) # 打印[<Element a at 0x2a215364988>]
# print(result[0].text) # 打印first item
result = tree.xpath('//*[@class="bold"]')
print(result[0].tag) # 返回标签,打印span
07_xpath案例实战/02_xpath.py:
"""
xpath是一个非常好用的解析方法,同时也作为爬虫学习的基础。
在后面的 selenium以及 scrapy框架中都会涉及到这部分知识,希望大家可以把它的语法掌握清楚,为后面的深入研究做好铺垫
xpath高级
/ 子节点
// 多层子节点
@ 选取某个属性
[] 选取条件
"""
from lxml import etree
parser = etree.HTMLParser(encoding='utf-8')
tree = etree.parse('02_xpath.html',parser=parser) # 如果碰到不规范的html文件时就会解析错误,自己创建html解析器,并增加parser参数
print(tree.xpath('//@code')) # 打印['84', '104', '223']
"""选取若干路径 | """
# 这个符号用于在一个xpath中写成多个表达式,用|分开,每个表达式互不干扰。顺序是按照HTML里的顺序来的
print(tree.xpath('//div[@id="testid"]/h2/text() | //li[@data]/text()')) # 打印['这里是个小标题', '1', '2', '3']
print(tree.xpath('//li[@data]/text() | //div[@id="testid"]/h2/text()')) # 打印['这里是个小标题', '1', '2', '3']
"""child,选取当前节点的所有子元素"""
# child:: 子节点定位
print(tree.xpath('//div[@id="testid"]/child::ul/li/text()')) # 打印['84内容', '104内容', '223内容']
# child::* 当前节点的所有子元素
print(tree.xpath('//div[@id="testid"]/child::*')) # 打印[<Element h2 at 0x228afc98c88>, <Element ol at 0x228afc98cc8>, <Element ul at 0x228afc98d08>]
# 定位当前节点下为ol的子节点下的所有节
print(tree.xpath('//div[@id="testid"]/child::ol/child::*/text()')) # 打印['1', '2', '3', '点我']
"""attribute选取当前节点的所有属性"""
# attribute::id定位id属性值
print(tree.xpath('//div/attribute::id')) # attribute定位id属性值,打印['testid', 'go', 'Lonelyroots']
print(tree.xpath('//div/@id')) # 打印['testid', 'go', 'Lonelyroots']
# attribute::*定位当前节点的所有属性
print(tree.xpath('//div[@id="testid"]/attribute::*')) # 打印['testid', 'first']
"""ancestor:父辈元素 / ancestor-or-self:父辈元素及当前元素"""
# 定位父辈div元素的price属性
print(tree.xpath('//div[@id="testid"]/ancestor::div/@price')) # 打印['99.8']
# 所有父辈div元素
print(tree.xpath('//div[@id="testid"]/ancestor::div')) # 打印[<Element div at 0x1ae7fd95ec8>]
# 所有父类及当前节点div元素
print(tree.xpath('//div[@id="testid"]/ancestor-or-self::div')) # 打印[<Element div at 0x280c7e28188>, <Element div at 0x280d7555ec8>]
"""following:选取文档中当前节点的结束标签【之后】的所有节点"""
# 定位testid之后不包含id属性的div标签下所有的li中第一个li的text属性
print(tree.xpath('//div[@id="testid"]/following::div[not(@id)]//li[1]/text()')) # 打印['test1']
print(tree.xpath('//div[@id="testid"]/following::div[@id="go"]//li[1]/text()')) # 打印['1']
"""preceding:选取文档中当前节点的开始标签【之前】的所有节点"""
# 记住是标签开始之前,同级前节点及其子节点
print(tree.xpath('//div[@id="testid"]/preceding::div/ul/li[1]/text()')) # 打印['时间']
"""parent:选取当前节点的父节点"""
# 选取data值为one的父节点的子节点中最后一个节点的值
print(tree.xpath('//li[@data="one"]/parent::ol/li[last()]/text()')) # 打印['3']
"""函数"""
"""count:统计"""
# 节点统计
print(tree.xpath('count(//li[@data])')) # 统计节点,打印3.0
"""concat:字符串连接"""
print(tree.xpath('concat(//li[@data="one"]/text(),//li[@data="three"]/text())')) # 打印 13
print(tree.xpath('concat(//li[@code="84"]/text(),//li[@code="223"]/text())')) # 打印 84内容223内容
"""contains(string1,string2):如果string1包含string2,则返回true,否则返回false"""
print(tree.xpath('//h3[contains(text(),"h3")]/a/text()')) # 打印['百度一下']
print(tree.xpath('//div[@id="go"]//li[contains(@class,"it1")]/text()')) # 打印['1', '5', '6']
"""not 布尔值(否)"""
print(tree.xpath('count(//li[not(@data)])')) # 打印 18.0
07_xpath案例实战/03_wallhaven提取.py:
"""
官网地址:
https://wallhaven.cc/latest
1. 请求当前页数 请求1
2. 拿出图片的ID
3. 拼接下载链接
4. 下载 请求2
jpg/png
【1】一边爬一边下
【2】先准备下载链接,再下载
a链接:href="https://wallhaven.cc/w/l3veoy"
缩略图img链接:https://th.wallhaven.cc/small/l3/l3veoy.jpg
下载的详细链接:https://w.wallhaven.cc/full/l3/wallhaven-l3veoy.png
"""
from requests_html import HTMLSession
import re
session = HTMLSession()
url = "https://wallhaven.cc/latest?page="
proxie = {
'http':'113.237.244.115:9999'
}
ImgUrlList = []
for page in range(1,2):
response = session.get(url=url+str(page),proxies=proxie)
imgUrl = response.html.xpath('//a[@class="preview"]/@href')
# 返回链接:如['https://wallhaven.cc/w/e7pdqr', 'https://wallhaven.cc/w/pkvrpm']
for url in imgUrl:
ImgUrlList.append(url)
print(ImgUrlList)
for imgUrl in ImgUrlList:
id = imgUrl[-6:]
suffix = 'jpg'
url = f"https://w.wallhaven.cc/full/{id[:2]}/wallhaven-{id}.{suffix}"
response = session.get(url=url)
if response.status_code != 200:
suffix = 'png'
url = f"https://w.wallhaven.cc/full/{id[:2]}/wallhaven-{id}.{suffix}"
response = session.get(url=url)
with open('images/{}.{}'.format(id,suffix),'wb') as fp:
fp.write(response.content)
print(f'============{id}下载完成============')
07_xpath案例实战/04_百度热搜.py:
from requests_html import HTMLSession
session = HTMLSession()
url = "https://top.baidu.com/board?tab=realtime"
response = session.get(url=url)
response.encoding = response.apparent_encoding
print(response.html.xpath('//div[@class="c-single-text-ellipsis"]/text()'))
文章到这里就结束了!希望大家能多多支持Python(系列)!六个月带大家学会Python,私聊我,可以问关于本文章的问题!以后每天都会发布新的文章,喜欢的点点关注!一个陪伴你学习Python的新青年!不管多忙都会更新下去,一起加油!
Editor:Lonelyroots