目录
Xpath
安装xpath
安装lxml库
导入lxml库
解析本地文件 etree.parse()
解析服务器响应文件 etree.HTML()
xpath基本语法
小案例:获取百度首页的百度一下
大案例:爬取站长素材图片
总结
Xpath
安装xpath
首先要学会安装Xpath,我这里很简单,没有到网络上搜索,直接使用魔法在谷歌商店直接搜索xpath就可以了,下载完成之后使用 ctrl + shift + x 就可以打开了。打开效果图如下:
安装lxml库
可以使用pip安装,命令如下
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple/ lxml
导入lxml库
from lxml import etree
解析本地文件 etree.parse()
html_tree = etree.parse('xx.html')
解析服务器响应文件 etree.HTML()
html_tree = etree.HTML(response.read().decode('utf-8'))
那么如果使用如下代码
html_cm_tree = etree.parse('17_解析_xpath.html')
print(html_cm_tree)
我的HTML代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>Title</title>
</head>
<body>
<ul>
<li id="l1" class="c1">北京</li>
<li id="l2">成都</li>
<li class="c2">深圳</li>
<li id="xl2">哈尔滨</li>
</ul>
<ul>
<li id="l3">大连</li>
<li id="xl1">长春</li>
<li class="c3">兰州</li>
<li>上海</li>
</ul>
</body>
</html>
这样就会报错
因为xpath严格遵守HTML规范,
这里要修改为
这样,单标签就要这样写
xpath基本语法
text() 获取标签中的内容
li_id_list = html_cm_tree.xpath('//ul/li[@id]/text()')
1.路径查询:
//:查找所有子孙节点,不考虑层级关系
/ :找直接子节点
# (1)查找ul 下面的li
# li_list = html_cm_tree.xpath('//body/ul/li')
# 下面这个写法也行
li_list = html_cm_tree.xpath('//body//li')
# 判断列表长度
print(li_list)
print(len(li_list))
2.谓词查询:
// div[@id]
// div[@id="maincontent"]
# (2)查找所有id的属性的li标签
li_id_list = html_cm_tree.xpath('//ul/li[@id]/text()')
print(li_id_list)
print(len(li_id_list))
# (3)查找id = l1的属性的li标签,id后面的必须要加 单引号
li_id1_list = html_cm_tree.xpath('//ul/li[@id="l1"]/text()')
print(li_id1_list)
print(len(li_id1_list))
3.属性查询:
//@class
# (4)查找id = l1的属性的li标签的class属性值
li_id1c_list = html_cm_tree.xpath('//ul/li[@id="l1"]/@class')
print(li_id1c_list)
print(len(li_id1c_list))
4.模糊查询:
//div[contains(@id, "he")]
// div[starts-with(@id,"he")]
# (5)查询 id 中包含l的li标签
li_idlll_list = html_cm_tree.xpath('//ul/li[contains(@id,"l")]/text()')
print(li_idlll_list)
print(len(li_idlll_list))
5.内容查询
//div/h1/text ()
如上使用了text()的都是
6.逻辑运算:
//div[@id="head"and@class="s_down"]
//title|//price
# (7)查询 id=l1 和class为c1的标签
li_idl1c1_list = html_cm_tree.xpath('//ul/li[@id="l1"and@class="c1"]/text()')
print(li_idl1c1_list)
print(len(li_idl1c1_list))
# (8)查询id=l1或者=l2的
li_titpri_list = html_cm_tree.xpath('//ul/li[@id="l1"]/text() | //ul/li[@id="l2"]/text()')
print(li_titpri_list)
print(len(li_titpri_list))
小案例:获取百度首页的百度一下
from lxml import etree
import urllib.request
# (1)获取网页源码
# (2)解析 解析的服务器响应的文件 etree.HTML
# (3)打印
url = 'https://www.baidu.com/'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36'
}
# 请求对象的定制
request = urllib.request.Request(url=url, headers=headers)
# 模拟浏览器访问服务器
response = urllib.request.urlopen(request)
# 获取网页源码
content = response.read().decode('utf-8')
# print(content)
# 解析网页源码,获取我们需要的数据
# 解析服务器响应的文件
tree = etree.HTML(content)
# 获取想要的数据,xpath的返回值是一个列表
result = tree.xpath('//input[@id="su"]/@value')
print(result)
大案例:爬取站长素材图片
import urllib.request
from lxml import etree
# (1)请求对象的定制
# (2)获取网页源码
# (3)下载
# 需求:下载前十页的图片
# 第一页地址
# https://sc.chinaz.com/tupian/taikongkexuetupian.html
# 第二页地址
# https://sc.chinaz.com/tupian/taikongkexuetupian_2.html
# 第三页地址
# https://sc.chinaz.com/tupian/taikongkexuetupian_3.html
"""
请求对象的定制
"""
def create_request(page):
if page == 1:
url = 'https://sc.chinaz.com/tupian/taikongkexuetupian.html'
else:
url = ('https://sc.chinaz.com/tupian/taikongkexuetupian_'
+ str(page) + '.html')
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36'
}
request = urllib.request.Request(url=url, headers=headers)
return request
"""
获取网页源码
"""
def get_content(request):
response = urllib.request.urlopen(request)
content = response.read().decode('utf-8')
return content
"""
下载
"""
def down_load(content):
# 下载图片
# urllib.request.urlretrieve('图片地址', '文件名')
tree = etree.HTML(content)
img_list = tree.xpath(
'//div[@class="container"]//img[@src="../static/common/com_images/img-loding.png"]/@data-original')
# 如果所爬取的网站是采用懒加载的方式,请使用懒加载前的地址访问
name_list = tree.xpath('//div[@class="container"]//img[@src="../static/common/com_images/img-loding.png"]/@alt')
for i in range(len(name_list)):
name = name_list[i]
img = img_list[i]
# 添加上协议地址,使得地址完整
url = 'https:' + img
# 下载
urllib.request.urlretrieve(url=url, filename='./站长素材爬取图片/' + name + '.jpg')
if __name__ == '__main__':
start_page = int(input("请输入起始页码"))
end_page = int(input("请输入结束页码"))
for page in range(start_page, end_page + 1):
# 1.请求对象的定制
request = create_request(page)
# 2.获取网页源码
content = get_content(request)
# 3.下载
down_load(content)
总结
ヾ( ̄▽ ̄)Bye~Bye~