python实现壁纸批量下载代码实例


Posted in Python onJanuary 25, 2018

项目地址:https://github.com/jrainlau/wallpaper-downloader

前言

好久没有写文章了,因为最近都在适应新的岗位,以及利用闲暇时间学习python。这篇文章是最近的一个python学习阶段性总结,开发了一个爬虫批量下载某壁纸网站的高清壁纸。

注意:本文所属项目仅用于python学习,严禁作为其他用途使用!

初始化项目

项目使用了virtualenv来创建一个虚拟环境,避免污染全局。使用pip3直接下载即可:

pip3 install virtualenv

然后在合适的地方新建一个wallpaper-downloader目录,使用virtualenv创建名为venv的虚拟环境:

virtualenv venv
. venv/bin/activate

接下来创建依赖目录:

echo bs4 lxml requests > requirements.txt

最后yun下载安装依赖即可:

pip3 install -r requirements.txt

分析爬虫工作步骤

为了简单起见,我们直接进入分类为“aero”的壁纸列表页:http://wallpaperswide.com/aer...。

python实现壁纸批量下载代码实例

可以看到,这一页里面一共有10张可供下载的壁纸。但是由于这里显示的都是缩略图,作为壁纸来说清晰度是远远不够的,所以我们需要进入壁纸详情页,去找到高清的下载链接。从第一张壁纸点进去,可以看到一个新的页面:

python实现壁纸批量下载代码实例

因为我机器是Retina屏幕,所以我打算直接下载体积最大的那个以保证高清(红圈所示体积)。

了解了具体的步骤以后,就是通过开发者工具找到对应的dom节点,提取相应的url即可,这个过程就不再展开了,读者自行尝试即可,下面进入编码部分。

访问页面

新建一个download.py文件,然后引入两个库:

from bs4 import BeautifulSoup
import requests

接下来,编写一个专门用于访问url,然后返回页面html的函数:

def visit_page(url):
 headers = {
  'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.108 Safari/537.36'
 }
 r = requests.get(url, headers = headers)
 r.encoding = 'utf-8'
 soup = BeautifulSoup(r.text, 'lxml')
 return soup

为了防止被网站反爬机制击中,所以我们需要通过在header添加UA把爬虫伪装成正常的浏览器,然后指定utf-8编码,最后返回字符串格式的html。

提取链接

在获取了页面的html以后,就需要提取这个页面壁纸列表所对应的url了:

def get_paper_link(page):
 links = page.select('#content > div > ul > li > div > div a')
 collect = []
 for link in links:
  collect.append(link.get('href'))
 return collect

这个函数会把列表页所有壁纸详情的url给提取出来。

下载壁纸

有了详情页的地址以后,我们就可以进去挑选合适的size了。在对页面的dom结构分析后可以知道,每一个size都对应着一个链接:

python实现壁纸批量下载代码实例

所以第一步,就是把这些size对应的链接提取出来:

wallpaper_source = visit_page(link)
wallpaper_size_links = wallpaper_source.select('#wallpaper-resolutions > a')
size_list = []
for link in wallpaper_size_links:
 href = link.get('href')
 size_list.append({
  'size': eval(link.get_text().replace('x', '*')),
  'name': href.replace('/download/', ''),
  'url': href
 })

size_list就是这些链接的一个集合。为了方便接下来选出最高清(体积最大)的壁纸,在size中我使用了eval方法,直接把这里的5120x3200给计算出来,作为size的值。

获取了所有的集合之后,就可以使用max()方法选出最高清的一项出来了:

biggest_one = max(size_list, key = lambda item: item['size'])

这个biggest_one当中的url就是对应size的下载链接,接下来只需要通过requests库把链接的资源下载下来即可:

result = requests.get(PAGE_DOMAIN + biggest_one['url'])
if result.status_code == 200:
 open('wallpapers/' + biggest_one['name'], 'wb').write(result.content)

注意,首先你需要在根目录下创建一个wallpapers目录,否则运行时会报错。

整理一下,完整的download_wallpaper函数长这样:

def download_wallpaper(link):
 wallpaper_source = visit_page(PAGE_DOMAIN + link)
 wallpaper_size_links = wallpaper_source.select('#wallpaper-resolutions > a')
 size_list = []
 for link in wallpaper_size_links:
  href = link.get('href')
  size_list.append({
   'size': eval(link.get_text().replace('x', '*')),
   'name': href.replace('/download/', ''),
   'url': href
  })
 biggest_one = max(size_list, key = lambda item: item['size'])
 print('Downloading the ' + str(index + 1) + '/' + str(total) + ' wallpaper: ' + biggest_one['name'])
 result = requests.get(PAGE_DOMAIN + biggest_one['url'])

 if result.status_code == 200:
  open('wallpapers/' + biggest_one['name'], 'wb').write(result.content)

批量运行

上述的步骤仅仅能够下载第一个壁纸列表页第一张壁纸。如果我们想下载多个列表页全部壁纸,我们就需要循环调用这些方法。首先我们定义几个常量:

import sys
if len(sys.argv) != 4:
 print('3 arguments were required but only find ' + str(len(sys.argv) - 1) + '!')
 exit()
category = sys.argv[1]
try:
 page_start = [int(sys.argv[2])]
 page_end = int(sys.argv[3])
except:
 print('The second and third arguments must be a number but not a string!')
 exit()

这里通过获取命令行参数,指定了三个常量category, page_startpage_end,分别对应着壁纸分类,起始页页码,终止页页码。

为了方便起见,再定义两个url相关的常量:

PAGE_DOMAIN = 'http://wallpaperswide.com'
PAGE_URL = 'http://wallpaperswide.com/' + category + '-desktop-wallpapers/page/'

接下来就可以愉快地进行批量操作了,在此之前我们来定义一个start()启动函数:

def start():
 if page_start[0] <= page_end:
  print('Preparing to download the ' + str(page_start[0]) + ' page of all the "' + category + '" wallpapers...')
  PAGE_SOURCE = visit_page(PAGE_URL + str(page_start[0]))
  WALLPAPER_LINKS = get_paper_link(PAGE_SOURCE)
  page_start[0] = page_start[0] + 1
  for index, link in enumerate(WALLPAPER_LINKS):
   download_wallpaper(link, index, len(WALLPAPER_LINKS), start)

然后把之前的download_wallpaper函数再改写一下:

def download_wallpaper(link, index, total, callback):
 wallpaper_source = visit_page(PAGE_DOMAIN + link)
 wallpaper_size_links = wallpaper_source.select('#wallpaper-resolutions > a')
 size_list = []
 for link in wallpaper_size_links:
  href = link.get('href')
  size_list.append({
   'size': eval(link.get_text().replace('x', '*')),
   'name': href.replace('/download/', ''),
   'url': href
  })
 biggest_one = max(size_list, key = lambda item: item['size'])
 print('Downloading the ' + str(index + 1) + '/' + str(total) + ' wallpaper: ' + biggest_one['name'])
 result = requests.get(PAGE_DOMAIN + biggest_one['url'])
 if result.status_code == 200:
  open('wallpapers/' + biggest_one['name'], 'wb').write(result.content)

 if index + 1 == total:
  print('Download completed!\n\n')
  callback()

最后指定一下启动规则:

if __name__ == '__main__':
  start()

运行项目

在命令行输入如下代码开始测试:

python3 download.py aero 1 2

然后可以看到下列输出:

python实现壁纸批量下载代码实例

拿charles抓一下包,可以看到正在脚本正在平稳地运行中:

python实现壁纸批量下载代码实例

此时,下载脚本已经开发完毕,终于不用担心壁纸荒啦!

以上就是本次为大家整理的全部内容,大家有任何疑问可以在下方的留言区讨论,感谢你对三水点靠木的支持。

Python 相关文章推荐
python中对list去重的多种方法
Sep 18 Python
详解在Python的Django框架中创建模板库的方法
Jul 20 Python
浅谈python正则的常用方法 覆盖范围70%以上
Mar 14 Python
Python读取txt文件数据的方法(用于接口自动化参数化数据)
Jun 27 Python
对Python中创建进程的两种方式以及进程池详解
Jan 14 Python
python绘制评估优化算法性能的测试函数
Jun 25 Python
Pycharm使用之设置代码字体大小和颜色主题的教程
Jul 12 Python
python生成器推导式用法简单示例
Oct 08 Python
基于Python3.6中的OpenCV实现图片色彩空间的转换
Feb 03 Python
python不相等的两个字符串的 if 条件判断为True详解
Mar 12 Python
Python 判断时间是否在时间区间内的实例
May 16 Python
keras 回调函数Callbacks 断点ModelCheckpoint教程
Jun 18 Python
python命令行解析之parse_known_args()函数和parse_args()使用区别介绍
Jan 24 #Python
Python动刷新抢12306火车票的代码(附源码)
Jan 24 #Python
python中的set实现不重复的排序原理
Jan 24 #Python
详解Python之unittest单元测试代码
Jan 24 #Python
python爬取拉勾网职位数据的方法
Jan 24 #Python
学习Python3 Dlib19.7进行人脸面部识别
Jan 24 #Python
Python实现的生成格雷码功能示例
Jan 24 #Python
You might like
支持中文、字母、数字的PHP验证码
2015/05/04 PHP
php在数据库抽象层简单使用PDO的方法
2015/11/03 PHP
PHP实现支持加盐的图片加密解密
2016/09/09 PHP
PHP实现的简单留言板功能示例【基于thinkPHP框架】
2018/12/07 PHP
Laravel 已登陆用户再次查看登陆页面的自动跳转设置方法
2019/09/30 PHP
javascript web对话框与弹出窗口
2009/02/22 Javascript
javascript 最常用的10个自定义函数[推荐]
2009/12/26 Javascript
jquery CSS选择器笔记
2010/03/29 Javascript
JavaScript作用域链示例分享
2014/05/27 Javascript
深入理解JavaScript系列(42):设计模式之原型模式详解
2015/03/04 Javascript
jquery+ajax请求且带返回值的代码
2015/08/12 Javascript
JS实现字符串转日期并比较大小实例分析
2015/12/09 Javascript
浅谈javascript中关于日期和时间的基础知识
2016/07/13 Javascript
EasyUI的doCellTip实现鼠标放到单元格上提示单元格内容
2016/08/24 Javascript
jQuery实现的省市联动菜单功能示例【测试可用】
2017/01/13 Javascript
Vue应用部署到服务器的正确方式
2017/07/15 Javascript
基于canvas实现手写签名(vue)
2020/05/21 Javascript
python安装教程 Pycharm安装详细教程
2017/05/02 Python
Python 3.6 读取并操作文件内容的实例
2018/04/23 Python
如何使用Python进行OCR识别图片中的文字
2019/04/01 Python
Python Tkinter 简单登录界面的实现
2019/06/14 Python
Python实现RabbitMQ6种消息模型的示例代码
2020/03/30 Python
python argparse传入布尔参数false不生效的解决
2020/04/20 Python
SIDESTEP荷兰:在线购买鞋子
2019/11/18 全球购物
写一个函数,要求输入一个字符串和一个字符长度,对该字符串进行分隔
2015/07/30 面试题
高校自主招生自荐信
2013/12/09 职场文书
销售主管岗位职责
2014/02/08 职场文书
会计工作决心书
2014/03/11 职场文书
生日寄语大全
2014/04/08 职场文书
《三个小伙伴》教学反思
2014/04/11 职场文书
班级学雷锋活动总结
2014/06/26 职场文书
大二学生学年自我鉴定
2014/09/12 职场文书
2014年发展党员工作总结
2014/11/12 职场文书
2016年大学生寒假社会实践心得体会
2015/10/09 职场文书
详解Java实践之适配器模式
2021/06/18 Java/Android
Pytest中skip skipif跳过用例详解
2021/06/30 Python