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 网络编程起步(Socket发送消息)
Sep 06 Python
python self,cls,decorator的理解
Jul 13 Python
Python面向对象编程中的类和对象学习教程
Mar 30 Python
Python数据结构之翻转链表
Feb 25 Python
Python进程间通信Queue消息队列用法分析
May 22 Python
python django框架中使用FastDFS分布式文件系统的安装方法
Jun 10 Python
django获取from表单multiple-select的value和id的方法
Jul 19 Python
决策树剪枝算法的python实现方法详解
Sep 18 Python
Python socket处理client连接过程解析
Mar 18 Python
keras 自定义loss损失函数,sample在loss上的加权和metric详解
May 23 Python
python 如何停止一个死循环的线程
Nov 24 Python
python3 实现mysql数据库连接池的示例代码
Apr 17 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
天使彦史上最神还原,性别曝光的那一刻,百万网友恋爱了
2020/03/02 国漫
用PHP和ACCESS写聊天室(二)
2006/10/09 PHP
解析php通过cookies获取远程网页的指定代码
2013/06/25 PHP
PHP防范SQL注入的具体方法详解(测试通过)
2014/05/09 PHP
如何写php守护进程(Daemon)
2015/12/30 PHP
Yii2.0框架模型添加/修改/删除数据操作示例
2019/07/18 PHP
快速保存网页中所有图片的方法
2006/06/23 Javascript
JavaScript的目的分析
2007/01/05 Javascript
使用JQuery和CSS模拟超链接的用户单击事件的实现代码
2012/05/23 Javascript
JS事件Event元素(兼容IE,Firefox,Chorme)
2012/11/01 Javascript
仿当当网淘宝网等主流电子商务网站商品分类导航菜单
2013/09/25 Javascript
jquery设置text的值示例(设置文本框 DIV 表单值)
2014/01/06 Javascript
jquery ajaxSubmit 异步提交的简单实现
2014/02/28 Javascript
JS实现单行文字不间断向上滚动的方法
2015/01/29 Javascript
JavaScript学习笔记之数组随机排序
2016/03/23 Javascript
微信小程序 this和that详解及简单实例
2017/02/13 Javascript
JavaScript实现滑块验证解锁
2021/01/07 Javascript
[42:25]2018DOTA2亚洲邀请赛 4.5 淘汰赛 LGD vs Liquid 第三场
2018/04/06 DOTA
完美解决Python2操作中文名文件乱码的问题
2017/01/04 Python
Python SQLite3数据库日期与时间常见函数用法分析
2017/08/14 Python
机器学习之KNN算法原理及Python实现方法详解
2018/07/09 Python
python使用matplotlib模块绘制多条折线图、散点图
2020/04/26 Python
详解Django将秒转换为xx天xx时xx分
2019/09/27 Python
python 递归调用返回None的问题及解决方法
2020/03/16 Python
PyCharm配置anaconda环境的步骤详解
2020/07/31 Python
python热力图实现简单方法
2021/01/29 Python
基于html5 canvas实现漫天飞雪效果实例
2014/09/10 HTML / CSS
荷兰家电销售网站:Welhof
2020/12/08 全球购物
城市规划毕业生求职信
2013/10/10 职场文书
大学活动邀请函
2014/01/28 职场文书
初一体育教学反思
2014/01/29 职场文书
中专毕业生的自荐书
2014/07/01 职场文书
2014年档案管理工作总结
2014/11/17 职场文书
2014年保管员工作总结
2014/11/18 职场文书
2015年学生管理工作总结
2015/05/26 职场文书
新生儿未入户证明
2015/06/23 职场文书