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 相关文章推荐
linux系统使用python获取cpu信息脚本分享
Jan 15 Python
python在指定目录下查找gif文件的方法
May 04 Python
Python调用命令行进度条的方法
May 05 Python
Python算法应用实战之栈详解
Feb 04 Python
对Python中type打开文件的方式介绍
Apr 28 Python
pytorch获取vgg16-feature层输出的例子
Aug 20 Python
python 使用pygame工具包实现贪吃蛇游戏(多彩版)
Oct 30 Python
浅谈图像处理中掩膜(mask)的意义
Feb 19 Python
解决pymysql cursor.fetchall() 获取不到数据的问题
May 15 Python
浅谈matplotlib中FigureCanvasXAgg的用法
Jun 16 Python
Python scrapy爬取小说代码案例详解
Jul 09 Python
Matlab使用Plot函数实现数据动态显示方法总结
Feb 25 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
咖啡的传说和历史
2021/03/03 新手入门
提示Trying to clone an uncloneable object of class Imagic的解决
2011/10/27 PHP
php页面消耗内存过大的处理办法
2013/03/18 PHP
php根据身份证号码计算年龄的实例代码
2014/01/18 PHP
php启用sphinx全文搜索的实现方法
2014/12/24 PHP
PHP读书笔记_运算符详解
2016/07/01 PHP
2010年最佳jQuery插件整理
2010/12/06 Javascript
jQuery的初始化与对象构建之浅析
2011/04/12 Javascript
javascript获取网页宽高方法汇总
2015/07/19 Javascript
JavaScript仿网易选项卡制作代码
2016/10/06 Javascript
Node.js 使用流实现读写同步边读边写功能
2017/09/11 Javascript
vue源码入口文件分析(推荐)
2018/01/30 Javascript
Vue.js组件间通信方式总结【推荐】
2018/11/23 Javascript
JS实现带阴历的日历功能详解
2019/01/24 Javascript
原生JS实现列表内容自动向上滚动效果
2019/05/22 Javascript
Vue extend的基本用法(实例详解)
2019/12/09 Javascript
前端开发之便利店收银系统代码
2019/12/27 Javascript
分析在Python中何种情况下需要使用断言
2015/04/01 Python
tensorflow 用矩阵运算替换for循环 用tf.tile而不写for的方法
2018/07/27 Python
NumPy 数组使用大全
2019/04/25 Python
Python自动化导出zabbix数据并发邮件脚本
2019/08/16 Python
python多任务之协程的使用详解
2019/08/26 Python
python numpy库linspace相同间隔采样的实现
2020/02/25 Python
Html5实现移动端、PC端 刮刮卡效果
2016/06/30 HTML / CSS
美国市场上最实惠的送餐服务:Dinnerly
2018/03/18 全球购物
法国亚马逊官方网站:Amazon.fr
2020/12/19 全球购物
继电保护工岗位职责
2014/01/05 职场文书
小学家长会邀请函
2014/01/23 职场文书
升国旗演讲稿
2014/09/05 职场文书
铣工实训报告
2014/11/05 职场文书
学术会议通知范文
2015/04/15 职场文书
合同纠纷调解书
2015/05/20 职场文书
董事会决议范本
2015/07/01 职场文书
初中英语教学反思范文
2016/02/15 职场文书
写一个Python脚本下载哔哩哔哩舞蹈区的所有视频
2021/05/31 Python
代码复现python目标检测yolo3详解预测
2022/05/06 Python