p.s.高产量博主,点个关注不迷路!(只需要源码的点击 IV)
目录
I.目标确定
II.查找接口并做xpath解析
III.代码实现思路与过程
IV.完整源码
本次实战的目的是加强xpath的理解和使用,目标是批量下载【站长素材】网站的美女图片,并且可以类推别的图片、数据网站。站长素材是国内最优质的几个素材网站,而且本次爬虫的目标图片完全免费开放,因此不涉及任何版权问题(求生欲!) 下图是部分的图片展示:
根据以往的经验,第一步是要寻找我们需要的接口,这些接口需要我们去探索:
1️⃣ 首先访问站长素材的官网,之后我们点击高清图片:
之后选择一种图片类型,哪一种都可以(方法完全相同),我们可以选择【亚洲美女】()
2️⃣ 接下来,按F12解析网页,选择Network,我们看到这样的内容:
这里什么都没有,是因为我们是先进入后按的F12,于是我们刷新一下页面,刷新后在Name列表的最上面有一个.html的文件,刚才选择其他图片类型的,这里也会有一个html文件,只是名称不同。
3️⃣ 选中刚才的html文件,我们发现这就是需要的接口,于是我们提取一下url和headers:
这是第一页的url,于是我们点击下面的翻页,翻到第二页和第三页,发现前三页的url是这样的:
https://sc.chinaz.com/tag_tupian/YaZhouMeiNv.htmlhttps://sc.chinaz.com/tag_tupian/yazhoumeinv_1.htmlhttps://sc.chinaz.com/tag_tupian/yazhoumeinv_2.html
这为后面的多页图片爬取提供了信息和思路。
4️⃣ 最后我们做一下xpath解析:首先我们点击Network下的Response:
接下来,我们查看一下所有的美女图片的链接在哪里:(查找对应的image标签)
找到之后,我们大概理一下它所在的结构,以及如何用xpath解析找到它:
通过上面的分析,我们得到了这样的一条路径:id值为container的div标签 - - - > a标签 - - - > img标签 - - - > img标签下的src属性
这些用xpath可以表示为:
//div[@id = "container"]//a/img/@src2
这里解释一下为什么不是src,学过前端的朋友知道src是图片的地址的属性,但是在网页没有展示图片的时候,图片会以懒加载的方式加载,于是src属性会变成src2,所以我们遇到src的时候一定要写成src2,否则无法爬到任何图片链接!
接下来,用相同的办法,我们获得了xpath表示的提取每一张图片名称的表达:
//div[@id = "container"]//a/img/@alt
p.s.图片名称在img标签的alt属性下,本身是图片加载不出来时用来填充页面的名称,但是也可以拿来作为图片的名称,我们拿到这个数据的原因是后面下载图片时使用该数据命名我们的图片文件!
前面的所有分析结束后,我们可以书写代码了:
1️⃣ 程序入口的书写:
首先,我们定义一下程序的入口:
if __name__ == '__main__':
start_page = int(input('请输入起始页码:'))
end_page = int(input('请输入终止页码:'))
for page in range(start_page,end_page + 1):
# 定制请求对象
create_request()
# 获取网页源码
get_content()
# 解析源码并下载图片
down_img()
入口是一个简单的读取起始与终止页面的代码,并且有一个for循环用于循环爬取图片,此时我们经过前面的分析,将整个任务分成三部分:定制请求对象、获取源码、解析源码并下载图片(此时还未书写这三部分对应的函数)。
2️⃣ 请求对象的定制:
这部分与之前的实战一模一样,不再赘述,如果不了解的可以查看这篇博客:
Python爬虫学习笔记_DAY_15_Python爬虫之urllib库实战篇【Python爬虫】_跳探戈的小龙虾的博客-CSDN博客
这部分的实现是这样的:
def create_request(page):
if(page == 1):
url = 'https://sc.chinaz.com/tag_tupian/YaZhouMeiNv.html'
else:
url = 'https://sc.chinaz.com/tag_tupian/yazhoumeinv_' + str(page) + '.html'
# print(url)
headers = {
'User-Agent' : 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36'
}
request = urllib.request.Request(url = url,headers = headers)
return request
不过要补充说明的是,url这部分是根据前面分析的每一页的url特点编写的:对于第一页,由于它与其他url都不同,我们用一个if单独判断,其他页通过 固定部分(https://sc.chinaz.com/tag_tupian/yazhoumeinv_) + 页码 + .html 组合得到。
3️⃣ 获取网页源码:
这部分也是很简单的,和之前也是一样的操作,我们先尝试通过urllib.request.urlopen()函数获取源码,经过尝试,我们的确可以只使用这个函数获取(没有其他反爬手段):
def get_content(request):
response = urllib.request.urlopen(request)
content = response.read().decode('utf-8')
return content
4️⃣ 解析源码并下载图片:
拿到源码后,我们可以用xpath解析它的源码了:
def down_img(content):
# 下载文件格式:urllib.request.urlretrieve('图片地址','文件的名字')
tree = etree.HTML(content)
name_list = tree.xpath('//div[@id = "container"]//a/img/@alt')
# 一般涉及到图片的网站,都会进行懒加载,要把src换成src2(懒加载时,src会以src2出现)
src_list = tree.xpath('//div[@id = "container"]//a/img/@src2')
# print(len(name_list))
# print(len(src_list))
for i in range(len(name_list)):
name = name_list[i]
src = src_list[i]
url = 'https:' + src
url = url.replace('_s','')
urllib.request.urlretrieve(url = url,filename= './zhanzhang/'+ name + '.jpg')
这里首先,我们通过etree.HTML()函数,将服务器响应的文件转换成tree对象,这是xpath解析服务器响应的方法(xpath也可以解析本地文件,这时使用另一个函数)。
之后,我们使用刚才分析的两句xpath解析语句,解析到所有的图片url和图片名称。
最后,用一个for循环,把图片的链接拼接一个https:,拼接的原因是,我们爬取的链接被自动隐去了https:,我们需要手动拼接!
补充:url.replace('_s','')这句代码是获取高清版本的意思,加上这句,图片会更加清晰!
最后,展示一下完整源码,仅供参考:
# xpath的实战:解析站长素材,下载指定页的图片
import urllib.request
from lxml import etree
# (1) 请求对象的定制
def create_request(page):
if(page == 1):
url = 'https://sc.chinaz.com/tag_tupian/YaZhouMeiNv.html'
else:
url = 'https://sc.chinaz.com/tag_tupian/yazhoumeinv_' + str(page) + '.html'
# print(url)
headers = {
'User-Agent' : 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36'
}
request = urllib.request.Request(url = url,headers = headers)
return request
# (2) 获取网页的源码
def get_content(request):
response = urllib.request.urlopen(request)
content = response.read().decode('utf-8')
return content
# (3) 下载图片
def down_img(content):
# 下载文件格式:urllib.request.urlretrieve('图片地址','文件的名字')
tree = etree.HTML(content)
name_list = tree.xpath('//div[@id = "container"]//a/img/@alt')
# 一般涉及到图片的网站,都会进行懒加载,要把src换成src2(懒加载时,src会以src2出现)
src_list = tree.xpath('//div[@id = "container"]//a/img/@src2')
# print(len(name_list))
# print(len(src_list))
for i in range(len(name_list)):
name = name_list[i]
src = src_list[i]
url = 'https:' + src
url = url.replace('_s','')
urllib.request.urlretrieve(url = url,filename= './zhanzhang/'+ name + '.jpg')
if __name__ == '__main__':
start_page = int(input('请输入起始页码:'))
end_page = int(input('请输入终止页码:'))
for page in range(start_page,end_page + 1):
# 定制请求对象
request = create_request(page)
# 获取网页源码
content = get_content(request)
# 解析源码并下载图片
down_img(content)
运行之前,记得在同级目录下,生成一个名称是 zhanzhang 的文件夹!