python批量下载网站马拉松照片的完整步骤


Posted in Python onDecember 05, 2018

前言

目前学习python几个月了,由于自己比较喜欢跑马拉松,已经跑过了很多场比赛,前些天就写了个简单的爬虫爬取了网上三千多场马拉松比赛的报名信息。

今年5月27日,我又参加了巴图鲁关门山壹佰越野50公里组的比赛,这里的“巴图鲁”源自蒙古语“英雄”的意思,这场比赛也是出了名的虐,地点在辽宁省本溪市 · 关门山国家森林公园,累计爬升3655m。当天早上六点准时出发,刚跑没多久就来了很长一段陡峭的台阶……此处省略一万字……最终经过很多小时的艰苦奋战完成了比赛。

赛后去官网想找几张好看的图片发朋友圈,打开官网赛事图片链接到了爱运动的一个网页http://runnerbar.com/yd_runnerbar/album/pc?type=3&activity_id=10712,这是个单页面的网页,不断滚动会自动加载更多的图片,我把页面一点点滚动找了很长一段时间根本找不到我的照片,刷新一下页面照片又从头开始了,实在不能忍。于是,我想要不把图片全部下载到本地查看吧,想干就干。

1. 分析

1.1 Chrome调试

在chrome浏览器里输入快捷键Cmd + Opt + I(Windows上是F12,或Ctrl + Shift + I),将调试选项切到Network,如下

python批量下载网站马拉松照片的完整步骤

一个个观察此网页发送的请求,找到和图片相关的请求

python批量下载网站马拉松照片的完整步骤

这是一个get请求,初步分析里面的参数,activity_id代表赛事id,page和pageSize分别代表页数和每页大小,接着将请求放在postman上印证

python批量下载网站马拉松照片的完整步骤

1.2请求分析

在postman里加了三个参数成功返回了一个json格式的值,第一阶段很顺利,接着分析里面的返回值,下面取了其中的一个元素

{
"album": {
 "activity_photo_count": 6984,
 "searchResultList": [
 {
  "id": "32926651",
  "uid": 50392,
  "name": "巴图鲁关东越野",
  "user_name": null,
  "user_img": "http://oss.runnerbar.com/img/user_upload/origin/20180526/1527305285356_fb59065d_18ce_478b_a3aa_259783f4cd5b.jpg",
  "create_time": 1527313780000,
  "image_height": 3648,
  "image_width": 5472,
  "orientation": 1,
  "url_hq": "http://oss.runnerbar.com/img/watermark/user_upload/origin/20180526/1527313783392_235c5cea_5d0c_4cd7_afc6_0ba37cdc7c1d.jpg?quality=h",
  "url_lq": "http://oss.runnerbar.com/img/watermark/user_upload/origin/20180526/1527313783867_7d986351_fde4_418a_8fb3_1723dcb38aec.jpg",
  "content": null,
  "is_like": 0,
  "like_count": null,
  "comment_count": 0
 }}

这是个json格式,最外层里有个album元素,album里包含了图片总数量activity_photo_count和图片信息的数组searchResultList。每张图片包含了id、uid、user_img、create_time等等,和图片路径相关的有三个值分别是user_img、url_hq、url_lq,其中的user_img打开后发现是赛事的宣传logo,剩下的url_hq、url_lq根据命名就很容易猜想到这是对应的两种尺寸的图片,用浏览器分别打开,果不其然正是想要的图片路径。

2.代码

2.1

上面已经知道了请求url和参数,下面就是需要将这些用代码实现出来。首先是发请求

url='http://m.yundong.runnerbar.com/yd_mobile/share/album.json'
para = {'activity_id':id,'page':page,'pageSize':100}
header = {}
r = requests.post(url,data=para,headers= header)

请求的返回值是json,json内容在上面已经贴出来了这里就不再重复,接着解析这个json

json_r = r.json()
parsed_json = json_r['album']['searchResultList']
activity = {}
items = []
count = json_r['album']['activity_photo_count']

这里就取到了图片总数量和图片信息的数组,这个请求参数是page和pageSize,一个请求只能取到一部分图片信息并不能把所有的图片都取出来。那能不能把所有图片分成一页返回呢?于是在postman上做了实验,将page=1,pageSize=10000发送,结果并不是想要的,真正返回的图片数量是100。说明这个接口做了校验,每个分页最大数量是100。看来投机取巧是不行了,分页还是要做的。

首先将单个请求封装成方法,传入page返回对应page的图片信息数组

def getRaceInfo(id,page):
 url='http://m.yundong.runnerbar.com/yd_mobile/share/album.json'
 para = {'activity_id':id,'page':page,'pageSize':100}
 header = {}
 r = requests.post(url,data=para,headers= header)
 json_r = r.json()
 parsed_json = json_r['album']['searchResultList']
 activity = {}
 items = []
 count = json_r['album']['activity_photo_count']
 for item in parsed_json:
 # print(item['user_img'])
 items.append(item)
 activity['items'] = items
 activity['count'] = count
return activity

图片的做数量是count,每页分100张图片,起点是第1页,那么总的分页数量就是count/100+2,分页的代码就应该是这样的

for i in range(1,int(count/100+2)):
 data = getRaceInfo(id,i)['items']

这里只是贴了一小段代码,完整代码可以参见上面的github地址

2.2 下载

有了图片在url,下载图片就更简单了,直接上代码

def save_img(img_url,file_name,file_path='book'):
#保存图片到磁盘文件夹 file_path中,默认为当前脚本运行目录下的 book\img文件夹
try:
 if not os.path.exists(file_path):
 print('文件夹',file_path,'不存在,重新建立')
 #os.mkdir(file_path)
 os.makedirs(file_path)
 #获得图片后缀
 file_suffix = os.path.splitext(img_url)[1]
 #拼接图片名(包含路径)
 filename = '{}{}{}{}'.format(file_path,os.sep,file_name,file_suffix)
 #下载图片,并保存到文件夹中
 urllib.request.urlretrieve(img_url,filename=filename)
except IOError as e:
 print('文件操作失败',e)
except HTTPError as e:
 print('Error code: ', e.code)
except Exception as e:
 print('错误 :',e)

运行python,查看本地文件

几千张图片很快下载到了本地

python批量下载网站马拉松照片的完整步骤

这时又有了新的想法,既然可以下载关门山越野的图片,是不是可以把爱运动里所有的图片都下载下来,说干就干。于是我将赛事id定义成参数,写个方法遍历id。改动了几行从新运行,几个小时后程序还在运行但是图片占用的大小已经超过了7G,

python批量下载网站马拉松照片的完整步骤

打开文件里面包含了各个赛事的图片,眼看图片越来越多加上我的mac存储空间有限最终停止了下载,但是这个思路应该是可行的。

源码地址: https://github.com/halibobo/runnerbar-image (本地下载)

最后

整个过程从开始到结束都在一天内完成的,代码里也没有什么复杂的逻辑,但完成之后心里还是有很多的满足感。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Python 相关文章推荐
python网络编程学习笔记(九):数据库客户端 DB-API
Jun 09 Python
Python使用pyodbc访问数据库操作方法详解
Jul 05 Python
Flask入门之上传文件到服务器的方法示例
Jul 18 Python
详解flask入门模板引擎
Jul 18 Python
Python生成验证码、计算具体日期是一年中的第几天实例代码详解
Oct 16 Python
基于python3实现倒叙字符串
Feb 18 Python
pandas DataFrame 数据选取,修改,切片的实现
Apr 24 Python
python中round函数如何使用
Jun 19 Python
基于python实现计算两组数据P值
Jul 10 Python
详细分析Python collections工具库
Jul 16 Python
Python+unittest+requests+excel实现接口自动化测试框架
Dec 23 Python
Python matplotlib 利用随机函数生成变化图形
Apr 26 Python
解决python3中cv2读取中文路径的问题
Dec 05 #Python
利用Python求阴影部分的面积实例代码
Dec 05 #Python
python之cv2与图像的载入、显示和保存实例
Dec 05 #Python
python存储16bit和32bit图像的实例
Dec 05 #Python
Python随机生成身份证号码及校验功能
Dec 04 #Python
python 从文件夹抽取图片另存的方法
Dec 04 #Python
使用Python实现微信提醒备忘录功能
Dec 04 #Python
You might like
php公用函数列表[正则]
2007/02/22 PHP
php 静态变量与自定义常量的使用方法
2010/01/26 PHP
php带密码功能并下载远程文件保存本地指定目录 修改加强版
2010/05/16 PHP
一些PHP Coding Tips(php小技巧)[2011/04/02最后更新]
2011/05/02 PHP
PHP函数实现从一个文本字符串中提取关键字的方法
2015/07/01 PHP
javascript 写的一个简单的timer
2009/07/30 Javascript
A标签中通过href和onclick传递的this对象实现思路
2013/04/19 Javascript
javascript动态创建表格及添加数据实例详解
2015/05/13 Javascript
AngularJS基础 ng-include 指令示例讲解
2016/08/01 Javascript
基于jQuery实现滚动刷新效果
2017/01/09 Javascript
原生js实现可拖拽效果
2017/02/28 Javascript
推荐VSCode 上特别好用的 Vue 插件之vetur
2017/09/14 Javascript
js实现图片粘贴上传到服务器并展示的实例
2017/11/08 Javascript
vue项目在安卓低版本机显示空白的原因分析(两种)
2018/09/04 Javascript
微信小程序使用template标签实现五星评分功能
2018/11/03 Javascript
angular使用md5,CryptoJS des加密的方法
2019/06/03 Javascript
谈谈我在vue-cli3中用预渲染遇到的坑
2020/04/22 Javascript
解决vue scoped scss 无效的问题
2020/09/04 Javascript
python2.7 mayavi 安装图文教程(推荐)
2017/06/22 Python
Python实现修改文件内容的方法分析
2018/03/25 Python
浅谈Python里面小数点精度的控制
2018/07/16 Python
使用Python制作自动推送微信消息提醒的备忘录功能
2018/09/06 Python
关于windows下Tensorflow和pytorch安装教程
2020/02/04 Python
DRF框架API版本管理实现方法解析
2020/08/21 Python
python与js主要区别点总结
2020/09/13 Python
如何使用html5与css3完成google涂鸦动画
2012/12/16 HTML / CSS
美国著名的团购网站:Woot
2016/08/02 全球购物
联想新加坡官方网站:Lenovo Singapore
2017/10/24 全球购物
为奢侈时尚带来了慈善元素:Olivela
2018/09/29 全球购物
流行文化收藏品:Sideshow(DC漫画,星球大战,漫威)
2019/03/17 全球购物
员工自我鉴定范文
2013/10/06 职场文书
绿化工程实施方案
2014/03/17 职场文书
村容村貌整治方案
2014/05/21 职场文书
考试作弊被抓检讨书
2014/10/02 职场文书
计算机专业自荐信范文
2015/03/26 职场文书
MySQL中InnoDB存储引擎的锁的基本使用教程
2021/05/26 MySQL