编写Python脚本批量下载DesktopNexus壁纸的教程


Posted in Python onMay 06, 2015

DesktopNexus 是我最喜爱的一个壁纸下载网站,上面有许多高质量的壁纸,几乎每天必上, 每月也必会坚持分享我这个月来收集的壁纸

但是 DesktopNexus 壁纸的下载很麻烦,而且因为壁纸会通过浏览器检测你当前分辨率来展示 合适你当前分辨率的壁纸,再加上是国外的网站,速度上很不乐观。

于是我写了个脚本,检测输入的页面中壁纸页面的链接,然后批量下载到指定文件夹中。

脚本使用 python 写的,所以需要机器上安装有 python 。
用法:

$ python desktop_nexus.py -p http://www.desktopnexus.com/tag/cat/ -s 1280x800 -o wallpapers

    -p 包含 DesktopNexus 壁纸链接的页面,比如我的壁纸分享
    -s 壁纸尺寸,可选,缺省为 1440x900
    -o 壁纸输出的文件夹,可选,缺省为当前目录下的 wallpapers, 如果不存在会自动创建

代码:

#-*- coding: utf-8 -*-
from argparse import ArgumentParser

import os, re, sys
import urllib2, cookielib, urlparse

RE_WALLPAPER = r'http\:\/\/[^\/\.]+\.desktopnexus\.com\/wallpaper\/\d+\/'
CHUNK_SIZE = 1024 * 3

class DesktopNexus:
  def __init__(self, page=None, size=None, output_dir=None):
    self.page = page
    self.size = size
    self.output_dir = output_dir

  def start(self):
    print 'Making output directory:', self.output_dir
    if not os.path.exists(self.output_dir):
      os.makedirs(self.output_dir)

    # Setup cookie
    cookie = cookielib.CookieJar()
    processer = urllib2.HTTPCookieProcessor(cookie)
    opener = urllib2.build_opener(processer)
    urllib2.install_opener(opener)

    self._read_page()

  def _get_pic_info(self, url):
    pic_id = url.split('/')[-2]
    html = urllib2.urlopen(url).read()
    pattern = r'<a href=\"\/get\/%s\/\?t=(?P<token>.*?)\"' % pic_id
    match = re.search(pattern, html, flags=re.I|re.M|re.S)
    if match:
      return {'id': pic_id,
          'token': match.group('token'),
          'size': self.size}
    else:
      raise Exception('Cound not find wallpaper')

  def _get_pic_file(self, pic_info):
    redirect_url = 'http://www.desktopnexus.com/dl/inline/%(id)s/%(size)s/%(token)s' % pic_info

    request = urllib2.urlopen(redirect_url)
    return request.geturl()

  def _download_pic(self, url):
    pic_info = self._get_pic_info(url)
    pic_file = self._get_pic_file(pic_info)
    filename = os.path.split(urlparse.urlparse(pic_file).path)[-1]
    filename = os.path.join(self.output_dir, filename)
    with open(filename, 'wb') as output:
      resp = urllib2.urlopen(pic_file)
      total_size = int(resp.info().get('Content-Length'))
      saved_size = 0.0
      while saved_size != total_size:
        chunk = resp.read(CHUNK_SIZE)
        saved_size += len(chunk)
        output.write(chunk)
        self._print_progress('Saving file: %s' % filename, \
            saved_size / total_size * 100)

  def _print_progress(self, msg, progress):
    sys.stdout.write('%-71s%3d%%\r' \
        % (len(msg) <= 70 and msg or msg[:67] + '...', progress))
    sys.stdout.flush()
    if progress >= 100:
      sys.stdout.write('\n')

  def _read_page(self):
    try:
      print 'Fetching content:', self.page
      html = urllib2.urlopen(self.page).read()
      links = set(re.findall(RE_WALLPAPER, html, re.M|re.I))
      count = len(links)

      print 'Downloading wallpapers:'
      for i, link in enumerate(links):
        print '[%d/%d]: %s' % (i + 1, count, link)
        try:
          self._download_pic(link)
        except Exception as e:
          print 'Error downloading wallpaper.', e.message
    except Exception as e:
      print 'Error fetching content.', e

if __name__ == '__main__':
  # Setup argparser
  parser = ArgumentParser('python desktop_nexus.py')
  parser.add_argument('-p', '--page', dest='page', required=True, \
      help='specific a page that includes wallpaper list')
  parser.add_argument('-s', '--size', dest='size', default='1440x900', \
      help='specific the wallpaper size, default to 1440x900')
  parser.add_argument('-o', '--output', dest='output_dir', default='wallpapers', \
      help='specific the output directory, default to "wallpapers"')
  args = parser.parse_args()
  dn = DesktopNexus(**args.__dict__)
  dn.start()

Python 相关文章推荐
python解析文件示例
Jan 23 Python
python使用MySQLdb访问mysql数据库的方法
Aug 03 Python
sublime text 3配置使用python操作方法
Jun 11 Python
python中判断文件编码的chardet(实例讲解)
Dec 21 Python
python文件操作之批量修改文件后缀名的方法
Aug 10 Python
python判断所输入的任意一个正整数是否为素数的两种方法
Jun 27 Python
在python plt图表中文字大小调节的方法
Jul 08 Python
django2笔记之路由path语法的实现
Jul 17 Python
python re模块匹配贪婪和非贪婪模式详解
Feb 11 Python
python解释器pycharm安装及环境变量配置教程图文详解
Feb 26 Python
python 使用递归实现打印一个数字的每一位示例
Feb 27 Python
pytest实现多进程与多线程运行超好用的插件
Jul 15 Python
在Windows服务器下用Apache和mod_wsgi配置Python应用的教程
May 06 #Python
利用Python脚本在Nginx和uwsgi上部署MoinMoin的教程
May 05 #Python
Python实现的HTTP并发测试完整示例
Apr 23 #Python
安装dbus-python的简要教程
May 05 #Python
使用SAE部署Python运行环境的教程
May 05 #Python
在Python中使用PIL模块对图片进行高斯模糊处理的教程
May 05 #Python
在Python中使用mechanize模块模拟浏览器功能
May 05 #Python
You might like
当海贼王变成JOJO风
2020/03/02 日漫
在PHP3中实现SESSION的功能(二)
2006/10/09 PHP
模板引擎Smarty深入浅出介绍
2006/12/06 PHP
php继承中方法重载(覆盖)的应用场合
2015/02/09 PHP
php使用substr()和strpos()联合查找字符串中某一特定字符的方法
2015/05/12 PHP
php字符串操作常见问题小结
2016/10/11 PHP
thinkphp 手机号和用户名同时登录
2017/01/20 PHP
判断页面是关闭还是刷新的js代码
2007/01/28 Javascript
jQuery 注意事项 与原因分析
2009/04/24 Javascript
探索Emberjs制作一个简单的Todo应用
2012/11/07 Javascript
Ext JS 4实现带week(星期)的日期选择控件(实战一)
2013/08/21 Javascript
js获取或设置当前窗口url参数的小例子
2013/10/14 Javascript
JavaScript继承基础讲解(原型链、借用构造函数、混合模式、原型式继承、寄生式继承、寄生组合式继承)
2014/08/16 Javascript
js窗口关闭提示信息(兼容IE和firefox)
2015/10/23 Javascript
AngularJS中如何使用$parse或$eval在运行时对Scope变量赋值
2016/01/25 Javascript
BootStrap实用代码片段之一
2016/03/22 Javascript
简单的分页代码js实现
2016/05/17 Javascript
浅谈js常用内置方法和对象
2016/09/24 Javascript
利用transition实现文字上下抖动的效果
2017/01/21 Javascript
原生JavaScript实现贪吃蛇游戏
2020/11/04 Javascript
[46:49]完美世界DOTA2联赛PWL S3 access vs Rebirth 第二场 12.19
2020/12/24 DOTA
Python语言描述KNN算法与Kd树
2017/12/13 Python
Python使用add_subplot与subplot画子图操作示例
2018/06/01 Python
详解pyenv下使用python matplotlib模块的问题解决
2018/11/29 Python
基于python-opencv3的图像显示和保存操作
2019/06/27 Python
Django之模板层的实现代码
2019/09/09 Python
如何运行带参数的python脚本
2019/11/15 Python
python中如何使用insert函数
2020/01/09 Python
通过python-pptx模块操作ppt文件的方法
2020/12/26 Python
关于python中remove的一些坑小结
2021/01/04 Python
清除canvas画布内容(点擦除+线擦除)
2020/08/12 HTML / CSS
全球速卖通巴西站点:Aliexpress巴西
2016/08/24 全球购物
请说出以下代码输出什么
2013/08/30 面试题
课程设计感想范文
2015/08/11 职场文书
python 定义函数 返回值只取其中一个的实现
2021/05/21 Python
vue+springboot实现登录验证码
2021/05/27 Vue.js