花瓣网,是国内著名的图片阅览网。有很多极具设计想法的图片,设计师可以在这里查找灵感。
今天,就来做一个爬虫,爬指定的图片。
第一步,分析花瓣网的AJAX
进入花瓣网,是个搜索框。
输入一个“网页设计”,进入搜索结果页面。往下拉动,图片还会自动增加,很明显这个是AJAX的结果。
F12,查看 network,分析下载的文件。主要分析 XHR(就是 XMLHttpRequest,AJAX 请求)。记得勾选“Preserve log” 保留每次刷新的文件目录。第一次打开,什么都看不到,需要刷新一下页面,进行加载就行了。
分别点这三个文件,看右边的 Reponse 响应结果,发现它们都跟页面内容无关,都是些不痛不痒的数据。
往下拉动页面,发现左边新增了一个文件,点它,果然页面数据就在这里了。
第二步,分析花瓣网的数据
把上面的那个文件,response 响应回来的内容复制出来,找个工具格式化。推荐 https://www.sojson.com/
但是发现这个JSON 里没有传统的图片地址~!!!
回到花瓣网的页面,Elements,查看图片
发现图片的地址本身就很诡异,不是传统的 jpg ,png 结尾。复制出来是这个样子:
//hbimg.huabanimg.com/68f6594f57ffcb237584802a95526886e98754655d057-zXvsGM_fw236
很明显用了CDN位置,完整路径应该是:
https://hbimg.huabanimg.com/68f6594f57ffcb237584802a95526886e98754655d057-zXvsGM_fw236
复制到浏览器地址栏中,果然打开了。
遂复制 68f6594f57ffcb237584802a95526886e98754655d057-zXvsGM_fw236 ,在刚刚那个 JSON 中去查找,居然找不到~!!
隐藏的够深~~!!
仔细观察,发现 68f6594f57ffcb237584802a95526886e98754655d057-zXvsGM_fw236 前面部分似乎就是 JSON 的 key 字段~!!
把后面的_fw236 去掉试试,还是可以打开图片。看来,花瓣隐藏的很深啊~!!!(写到这里,把刚刚那个字段弄丢了,原图不知道是哪个了,就换个字段,道理是一样的。尴尬~)
https://hbimg.huabanimg.com/af8ee6b8aa9bbe64146ef5c6e2491cedb49f3a90126be7-EJu5cA
(点开,还是可以看到图片)也就是说,我们用 https://hbimg.huabanimg.com/ 结合 JSON 的key 字段,就可以得到 图片的地址。
果然找到:(刚刚那个字段丢了,重新截图一个,是其他的数据,道理一样的。)
步骤三:分析 JSON 地址和请求参数
看下那个文件的地址和请求方法,原来是 get 方式,那么地址后面的参数就用 params 添加。
猜都猜的到,page 是第2 页的数据,每页20个。如果把 page 改成1,per_page 改成 50,就是获取了前 50 张图。
不敢爬太多,怕花瓣封我的 IP,还是低调点。
爬虫,千万不要影响网站的正常运营,否则就犯法了,进橘子就不好玩了~~
第四步,编码
# -*- coding:utf-8 -*-
import requests,os,json
baseurl = "https://hbimg.huabanimg.com/" # 图片地址公用部分
imgs = [] # 图片存储的list
weburl = r"https://huaban.com/search" # 请求地址
kw = input("请输入你要查找的图片:") # 添加个输入,这样要什么图,自己写就是
# 构建 get 参数。
params = {
"q": kw,
"k765peeh":"",
"page": 1,
"per_page": 50,
"wfl": 1
}
# 设置请求 headers,伪装浏览器 并接受中文数据
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36'
}
req = requests.get( url=weburl, params=params, headers=headers)
req.encoding="utf-8" # 设置请求编码
# 这个地方画板有个坑,请求的结果是搜索结果HTML页面。数据在第19行~!!
req_json_txt = req.text.split("\n")[18] # 获取数据相关字符串
# 字符串的第19个字符开始到倒数第二个字符是 json 字符串,最后一个符号是分号。
# 这里不详细解释,大家自己操作下就知道了。
# print( req_json_txt )
req_json =json.loads(req_json_txt[18:-1]) # 把字符串转为 JSON,其实是 list 列表数据。
# print( req_json )
# 列表的每个元素都是 dict,图片名字就放在 file 字段的 key 字段里。
for item in req_json :
imgs.append( baseurl+ item["file"]["key"] ) # 拼接图片数组
# print( imgs )
# 遍历图片地址 list,下载对应图片到指定文件夹中。文件名用的是网络中的名字。
for item in imgs:
img_req = requests.get(item,headers=headers)
with open("huaban/"+item.split("/")[-1]+".jpg", "wb" ) as f:
f.write(img_req.content)
详细代码就不解释了,请看注释。
这里有个小坑,就是请求的结果居然是 搜索结果 HTML,而不是我以为的单纯的JSON,而且这个页面还是 VUE写的。好在数据都在页面上,就用以下代码获取对应字符串。
req_json_txt = req.text.split("\n")[18]
搜索的“美人”图,关键还是大图,不是缩略小图。花瓣真良心~哈哈,虽然不是超大的图,但是作为设计灵感的参考,我觉得完全够用~!!如果要想获得更多的图,修改参数就行。但是不要太多,贪心可不好哦~