本文主要介绍的技术要点:
- 无法使用F12调出抓包工具
- js反爬
- 基于人道主义,国内很良心的壁纸,希望各位做只善良的爬虫
从上面我们可以看出抓包获取到的图片网址的大小和网页中展示给出的比例不一样,同时从a标签的网址中我们看出图片应该为缩略图,只是用来展示。
既然在网页源代码中找不到图片,我们则一直加载图片,发现其实动态加载,则我们可以从抓包工具的Network中查找
一般动态加载的文件都放到了XHR这个选项中,随着滑动滚轮,我们发现getJson这个文件一直在增加,由此断定图片的网址在这里
但是当我们打开文件的内容时,发现是这些东西
当时就处于了懵逼状态,这是什么了(我的fuck)然后放弃了……
当然这是不可能的,既然动态加载获取的是这些东西,那应该与图片的地址肯定有关系,于是在我点开一张图片时
发现抓包工具中多出来一个网址,然后获取到网址打开一看,果然是图片的地址,这样我们就获取到了图片的地址
我们多获取一些图片的地址,看其中有什么区别:
https://w.wallhaven.cc/full/5w/wallhaven-5wo3j8.jpg
https://w.wallhaven.cc/full/ym/wallhaven-ym3veg.jpg
https://w.wallhaven.cc/full/83/wallhaven-836rgy.jpg
我们可以发现每个网址大体就是后面的不一样,同时突然想起了getJson中的源码,在其源码中搜索5wo3j8
由此我们知道了这里面这个就是图片地址中的部分,我们只需获取到getJson中的源码即可。
当我们查看getJson的请求时,发现是post请求(啊,好久没用过post请求了,然后打开笔记又看了下post请求的过程)
首先编写请求头
headers = {
"accept-encoding": "gzip,deflate,br",
"accept-language": "zh-CN, zh,q = 0.9, en - US,q = 0.8, en,q = 0.7, zh - TW,q = 0.6",
"access": "918c3eb8f5d471ffdc7a34365152b220b07d8bdc5c991a47961564a62b84834",
"content-length": "30",
"content-type": "application/json",
"location": "bz.zzzmh.cn",
"origin": "https://bz.zzzmh.cn",
"referer": "https://bz.zzzmh.cn/",
"sign": "273a3b6b44a285e367af744c37eb30f6",
"timestamp": "1614348146725",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36",
}
在这里我们分析下每个getJson页面的请求头
我们会发现每个getJson文件的access和timestamp不一样
这里的access使用了加密算法(安全散列算法)
至于这里如何加密的,我们需要查看access的形成
import time
import hashlib
timestamp = str(int(time.time()*1000)) # 时间戳的长度要与请求到的时间戳对应
# print(timestamp)
access = "application/json" + "bz.zzzmh.cn" + "273a3b6b44a285e367af744c37eb30f6"+ timestamp
access = hashlib.sha256(access.encode("utf-8")).hexdigest()
在这里我们获取到了access和timestamp
至此我们可以编写代码了
import json
import requests
import time
import hashlib
"""
post请求需要携带参数
"content-type": "application/json"
当content-type的值为json格式时,post请求时必须为json格式
当content-type的值为键值对格式时,post请求时必须为键值对格式
每个网址不一样的地方
timestamp: 时间戳
access:
加密算法:sha家族(安全散列算法)
"""
timestamp = str(int(time.time()*1000)) # 时间戳的长度要与请求到的时间戳对应
# print(timestamp)
access = "application/json" + "bz.zzzmh.cn" + "273a3b6b44a285e367af744c37eb30f6"+ timestamp
access = hashlib.sha256(access.encode("utf-8")).hexdigest()
def main():
url = "https://api.zzzmh.cn/bz/getJson"
headers = {
"accept-encoding": "gzip,deflate,br",
"accept-language": "zh-CN, zh,q = 0.9, en - US,q = 0.8, en,q = 0.7, zh - TW,q = 0.6",
"access": access,
"content-length": "30",
"content-type": "application/json",
"location": "bz.zzzmh.cn",
"origin": "https://bz.zzzmh.cn",
"referer": "https://bz.zzzmh.cn/",
"sign": "273a3b6b44a285e367af744c37eb30f6",
"timestamp": timestamp,
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36",
}
data = {
"pageNum": "1",
"target": "index"
}
response = requests.post(url, headers=headers, data=json.dumps(data)).json()
imageList = response.get("result").get("records")
for image in imageList:
imageType = image.get("t")
imageNum = image.get("i")
newurl = "https://w.wallhaven.cc/full/{}/wallhaven-{}.{}"
if imageType == "j":
newurl = newurl.format(imageNum[:2],imageNum, "jpg")
elif imageType == "p":
newurl = newurl.format(imageNum[:2],imageNum, "png")
print("正在下载:"+newurl)
image = requests.get(newurl).content
path = "D:\Code\spider\douban\python爬虫进阶\图片\\" + imageNum + ".jpg"
with open(path, 'wb') as f:
f.write(image)
if __name__ == '__main__':
main()
以后就是获取极简壁纸的高清壁纸的过程,其中的重点是js逆向,access的获取。