Python3 爬虫从unsplash网站抓取高清大图

在互联网上访问网站(系统)时,服务器上的反馈方式有两种:一种是直接向用户返回一个静态html页面,这个页面及其内容在用户访问之前就已经完整存在于服务器某一路径上;另一种是根据用户的请求,先从数据库加载相关数据,形成网页反馈给用户,页面的数据还会根据用户的访问或者数据库的数据更新而自动更新。

Python3 爬虫从网站抓取图片(一)练习了从中央政府网站抓取图片,它的网页内容就是前一种反馈和存储方式,链接都被静态化存储在html页面中,使用BeautifulSoup库可以很好处理。

百度等搜索网站、淘宝京东等购物网站和买卖股票网站都属于后一类。这次选择一个免费的摄影作品网站(unsplash.com)进行抓取图片练习。这个网站也推荐给大家,需要各种美图的朋友可以从这里找到自己喜欢的照片。

Python3 爬虫从unsplash网站抓取高清大图

在搜索框输入一个主题,比如我们查找与中国有关的图片。可以看到这个网站对于同一主题的图片是放在固定的路径之下:/s/photos/china。

Python3 爬虫从unsplash网站抓取高清大图

与中国有关的图片一共搜到5700+张,每张图片下放显示名称。鼠标移动到图片右下角会有一个下载箭头,最下边就会显示下载链接。这个链接很有特点,不同照片的下载链接只有photos和download之间的部分不一样,这部分应该就是每一张图片的实际ID或者存放名称。

Python3 爬虫从unsplash网站抓取高清大图

接下来的任务就是找到这些ID的存储位置。前面已经讲过,这个网站属于动态加载数据的一类网站,这就需要F12打开浏览器的开发人员工具查看。可是在查看了所有js脚本,都没有发现相关数据。

Python3 爬虫从unsplash网站抓取高清大图

动态加载图片的网站都有一个特点,就是继续下拉会出现新的图片。操作之后,果然出现了一个存储数据内容的脚本,里面包含图片id,links下还有这张照片的下载链接。

Python3 爬虫从unsplash网站抓取高清大图

继续分析这个脚本的路径:后面的参数表明,网站加载了china主题的图片,默认每页加载显示20张,当下是第2页。可以通过修改query、per_page和page 3个参数加载我们想要现在的图片主题和数量。

Python3 爬虫从unsplash网站抓取高清大图

下面开始编写代码,定义3个主要函数:

获取页面Response对象的getHtmlResponse(url)函数,这里给headers加入两个参数“User-Agent”和“Referer”,让爬虫更像是人在访问,而且是从unsplash网站一步一步操作的。同时,处理ssl安全认证,将requests.get()函数的verify=False,这时会有警告信息,使用urllib3模块的disable_warnings()使其不予显示。

Python3 爬虫从unsplash网站抓取高清大图

下载一张图片的getPicture(url,theme,name)函数,输入链接ulr,存储路径path和文件名name三个参数。根据主题theme创建文件夹,将下载的图片存放在同一主题目录下。

Python3 爬虫从unsplash网站抓取高清大图

下载1页20张图片的getOnePage(url,path)。从links:download获取下载链接,并确定下载尺寸,这里选定宽度为1920。获取“alt_description”的值命名文件。

Python3 爬虫从unsplash网站抓取高清大图

最后定义主函数,由用户输入需要下载的主题和数量。

Python3 爬虫从unsplash网站抓取高清大图

完整代码如下:

<code># _*_ coding:utf-8 _*_

import requests
import math
import json
import os
from requests.packages import urllib3

# 获取页面Response
def getHtmlResponse(url):
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36 Edg/80.0.361.69',
'Referer': 'https://unsplash.com/'
}

try:
urllib3.disable_warnings()
r = requests.get(url,verify=False,headers=headers)
r.raise_for_status()
r.encoding = r.apparent_encoding
return r
except Exception as e:
return ''

# 下载一张图片
def getPicture(url,path,name):
try:
req = getHtmlResponse(url)
if not os.path.exists(path):
os.makedirs(path)
with open(path+name,'wb') as f:
f.write(req.content)
f.flush()
except Exception as e:
return ''

# 下载一页20张图片
def getOnePage(url,path):
req = getHtmlResponse(url)
html = req.text
data = json.loads(html)
# getPicture(url)
count = 0
for result in data['results']:

count = count + 1
# 获取“alt_description”命名文件
name = result['alt_description']+'.jpg'
# 获取下载链接,并确定下载尺寸,这里选定宽度为1920
pic_url = result['links']['download']+'?force=true&w=1920'
print('正在下载第%d张照片:%s……' % (count,name))
getPicture(pic_url,path,name)

# 主函数
if __name__ == '__main__':
theme = input('请输入要下载的照片主题:')
path = theme + '/'
num = int(input('请输入下载数量:'))
page_num = math.ceil(num/20)

for i in range(1,page_num+1):
url = 'http://unsplash.com/napi/search/photos?query='+theme+'&per_page=20&page='+str(i)
getOnePage(url,path)
print('第'+ i +'页下载完毕')

print('%d张%s主题的照片全部下载完成!' % (num,theme))/<code>

最后运行效果:

Python3 爬虫从unsplash网站抓取高清大图

选择一张图片看看:

Python3 爬虫从unsplash网站抓取高清大图


分享到:


相關文章: