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实现ipsec开权限实例
Nov 11 Python
给Python入门者的一些编程建议
Jun 15 Python
python bottle框架支持jquery ajax的RESTful风格的PUT和DELETE方法
May 24 Python
Pandas删除数据的几种情况(小结)
Jun 21 Python
Python 旋转打印各种矩形的方法
Jul 09 Python
python flask几分钟实现web服务的例子
Jul 26 Python
python使用writerows写csv文件产生多余空行的处理方法
Aug 01 Python
使用OpenCV实现仿射变换—平移功能
Aug 29 Python
python lambda表达式(匿名函数)写法解析
Sep 16 Python
Python+opencv+pyaudio实现带声音屏幕录制
Dec 23 Python
np.random.seed() 的使用详解
Jan 14 Python
如何把python项目部署到linux服务器
Aug 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
探讨多键值cookie(php中cookie存取数组)的详解
2013/06/06 PHP
ThinkPHP水印功能实现修复PNG透明水印并增加JPEG图片质量可调整
2014/11/05 PHP
ThinkPHP处理Ajax返回的方法
2014/11/22 PHP
如何使用php等比例缩放图片
2016/10/12 PHP
PHP合并两个或多个数组的方法
2019/01/20 PHP
纯CSS3代码实现滑动开关效果
2015/08/19 Javascript
js随机生成字母数字组合的字符串 随机动画数字
2015/09/02 Javascript
详解微信小程序开发之下拉刷新 上拉加载
2016/11/24 Javascript
用javascript获取任意颜色的更亮或更暗颜色值示例代码
2017/07/21 Javascript
史上最全JavaScript数组去重的十种方法(推荐)
2017/08/17 Javascript
微信小程序版翻牌小游戏
2018/01/26 Javascript
浅谈用Webpack路径压缩图片上传尺寸获取的问题
2018/02/22 Javascript
代码整洁之道(重构)
2018/10/25 Javascript
vue2中引用及使用 better-scroll的方法详解
2018/11/15 Javascript
vue中使用百度脑图kityminder-core二次开发的实现
2019/09/26 Javascript
vue element-ul实现展开和收起功能的实例代码
2020/11/25 Vue.js
浅析Python中元祖、列表和字典的区别
2016/08/17 Python
Python自动化运维之IP地址处理模块详解
2017/12/10 Python
Python读取本地文件并解析网页元素的方法
2018/05/21 Python
解决使用pycharm提交代码时冲突之后文件丢失找回的方法
2018/08/05 Python
通过python将大量文件按修改时间分类的方法
2018/10/17 Python
使用Django开发简单接口实现文章增删改查
2019/05/09 Python
python实践项目之监控当前联网状态详情
2019/05/23 Python
Python提取PDF内容的方法(文本、图像、线条等)
2019/09/25 Python
使用python快速在局域网内搭建http传输文件服务的方法
2019/11/14 Python
pytorch中的transforms模块实例详解
2019/12/31 Python
解决PyCharm不在run输出运行结果而不是再Console里输出的问题
2020/09/21 Python
详解window.open被浏览器拦截的解决方案
2019/07/18 HTML / CSS
Html5饼图绘制实现统计图的方法
2020/08/05 HTML / CSS
工作失职检讨书范文
2014/01/16 职场文书
党的群众路线教育实践活动个人对照检查材料范文
2014/09/25 职场文书
迟到检讨书2000字(精选篇)
2014/10/07 职场文书
学生违纪检讨书200字
2014/10/21 职场文书
党校学习个人总结
2015/02/15 职场文书
2015年征兵工作总结
2015/07/23 职场文书
2016幼儿园教师节新闻稿
2015/11/25 职场文书