70行python代码实现壁纸批量下载!爬虫就是这么简

初始化项目

本文来自小莫扎特博客www.plusminustsuchi.com 提供

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

本文来自小莫扎特博客www.plusminustsuchi.com 提供

pip3 install virtualenv
 本文来自小莫扎特博客www.plusminustsuchi.com 提供 

然后在合适的地方新建一个wallpaper-downloader目录,使用virtualenv创建名为venv的虚拟环境: 本文来自小莫扎特博客www.plusminustsuchi.com 提供

virtualenv venv
. venv/bin/activate
 本文来自小莫扎特博客www.plusminustsuchi.com 提供 

接下来创建依赖目录: 本文来自小莫扎特博客www.plusminustsuchi.com 提供

echo bs4 lxml requests < requirements.txt
 

本文来自小莫扎特博客www.plusminustsuchi.com 提供

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

本文来自小莫扎特博客www.plusminustsuchi.com 提供

pip3 install -r requirements.txt
 本文来自小莫扎特博客www.plusminustsuchi.com 提供 

分析爬虫工作步骤

本文来自小莫扎特博客www.plusminustsuchi.com 提供

私信小编01 02 03 04 即可获取数十套PDF哦!

本文来自小莫扎特博客www.plusminustsuchi.com 提供

为了简单起见,我们直接进入分类为“aero”的壁纸列表页:

本文来自小莫扎特博客www.plusminustsuchi.com 提供

 

本文来自小莫扎特博客www.plusminustsuchi.com 提供

 

本文来自小莫扎特博客www.plusminustsuchi.com 提供

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

 

本文来自小莫扎特博客www.plusminustsuchi.com 提供

  本文来自小莫扎特博客www.plusminustsuchi.com 提供

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

本文来自小莫扎特博客www.plusminustsuchi.com 提供

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

本文来自小莫扎特博客www.plusminustsuchi.com 提供

访问页面 本文来自小莫扎特博客www.plusminustsuchi.com 提供

新建一个文件,然后引入两个库: 本文来自小莫扎特博客www.plusminustsuchi.com 提供

from bs4 import BeautifulSoup
import requests
 

本文来自小莫扎特博客www.plusminustsuchi.com 提供

接下来,编写一个专门用于访问url,然后返回页面html的函数: 本文来自小莫扎特博客www.plusminustsuchi.com 提供

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

本文来自小莫扎特博客www.plusminustsuchi.com 提供

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

本文来自小莫扎特博客www.plusminustsuchi.com 提供

提取链接

本文来自小莫扎特博客www.plusminustsuchi.com 提供

在获取了页面的html以后,就需要提取这个页面壁纸列表所对应的url了: 本文来自小莫扎特博客www.plusminustsuchi.com 提供

def get_paper_link(page):
 links = ('#content < div < ul < li < div < div a')
 return [('href') for link in links]
 本文来自小莫扎特博客www.plusminustsuchi.com 提供 

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

本文来自小莫扎特博客www.plusminustsuchi.com 提供

下载壁纸 本文来自小莫扎特博客www.plusminustsuchi.com 提供

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

本文来自小莫扎特博客www.plusminustsuchi.com 提供

 

本文来自小莫扎特博客www.plusminustsuchi.com 提供

  本文来自小莫扎特博客www.plusminustsuchi.com 提供

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

本文来自小莫扎特博客www.plusminustsuchi.com 提供

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

本文来自小莫扎特博客www.plusminustsuchi.com 提供

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

本文来自小莫扎特博客www.plusminustsuchi.com 提供

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

本文来自小莫扎特博客www.plusminustsuchi.com 提供

biggest_one = max(size_list, key = lambda item: item['size'])
 本文来自小莫扎特博客www.plusminustsuchi.com 提供 

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

本文来自小莫扎特博客www.plusminustsuchi.com 提供

result = (PAGE_DOMAIN + biggest_one['url'])
if result.status_code == 200:
 open('wallpapers/' + biggest_one['name'], 'wb').write()
 本文来自小莫扎特博客www.plusminustsuchi.com 提供 

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

本文来自小莫扎特博客www.plusminustsuchi.com 提供

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

本文来自小莫扎特博客www.plusminustsuchi.com 提供

def download_wallpaper(link):
 wallpaper_source = visit_page(PAGE_DOMAIN + link)
 wallpaper_size_links = ('#wallpaper-resolutions < a')
 size_list = [{
 'size': eval(_text().replace('x', '*')),
 'name': ('href').replace('/download/', ''),
 'url': ('href')
 } for link in wallpaper_size_links]
 biggest_one = max(size_list, key = lambda item: item['size'])
 print('Downloading the ' + str(index + 1) + '/' + str(total) + ' wallpaper: ' + biggest_one['name'])
 result = (PAGE_DOMAIN + biggest_one['url'])
 if result.status_code == 200:
 open('wallpapers/' + biggest_one['name'], 'wb').write()
 
本文来自小莫扎特博客www.plusminustsuchi.com 提供

批量运行

本文来自小莫扎特博客www.plusminustsuchi.com 提供

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

本文来自小莫扎特博客www.plusminustsuchi.com 提供

import sys
if len() != 4:
 print('3 arguments were required but only find ' + str(len() - 1) + '!')
 exit()
category = [1]
try:
 page_start = [int([2])]
 page_end = int([3])
except:
 print('The second and third arguments must be a number but not a string!')
 exit()
 
本文来自小莫扎特博客www.plusminustsuchi.com 提供

这里通过获取命令行参数,指定了三个常量category, page_start和page_end,分别对应着壁纸分类,起始页页码,终止页页码。 本文来自小莫扎特博客www.plusminustsuchi.com 提供

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

本文来自小莫扎特博客www.plusminustsuchi.com 提供

PAGE_DOMAIN = ''
PAGE_URL = '/' + category + '-desktop-wallpapers/page/'
 本文来自小莫扎特博客www.plusminustsuchi.com 提供 

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

本文来自小莫扎特博客www.plusminustsuchi.com 提供

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)
 
本文来自小莫扎特博客www.plusminustsuchi.com 提供

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

本文来自小莫扎特博客www.plusminustsuchi.com 提供

def download_wallpaper(link, index, total, callback):
 wallpaper_source = visit_page(PAGE_DOMAIN + link)
 wallpaper_size_links = ('#wallpaper-resolutions < a')
 size_list = [{
 'size': eval(_text().replace('x', '*')),
 'name': ('href').replace('/download/', ''),
 'url': ('href')
 } for link in wallpaper_size_links]
 biggest_one = max(size_list, key = lambda item: item['size'])
 print('Downloading the ' + str(index + 1) + '/' + str(total) + ' wallpaper: ' + biggest_one['name'])
 result = (PAGE_DOMAIN + biggest_one['url'])
 if result.status_code == 200:
 open('wallpapers/' + biggest_one['name'], 'wb').write()
 if index + 1 == total:
 print('Download completed!\n\n')
 callback()
 本文来自小莫扎特博客www.plusminustsuchi.com 提供 

最后指定一下启动规则: 本文来自小莫扎特博客www.plusminustsuchi.com 提供

if __name__ == '__main__':
 start()
 本文来自小莫扎特博客www.plusminustsuchi.com 提供 

运行项目 本文来自小莫扎特博客www.plusminustsuchi.com 提供

在命令行输入如下代码开始测试: 本文来自小莫扎特博客www.plusminustsuchi.com 提供

python3  aero 1 2
 本文来自小莫扎特博客www.plusminustsuchi.com 提供 

然后可以看到下列输出: 本文来自小莫扎特博客www.plusminustsuchi.com 提供

 

本文来自小莫扎特博客www.plusminustsuchi.com 提供

  本文来自小莫扎特博客www.plusminustsuchi.com 提供

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

本文来自小莫扎特博客www.plusminustsuchi.com 提供

 

本文来自小莫扎特博客www.plusminustsuchi.com 提供

  本文来自小莫扎特博客www.plusminustsuchi.com 提供

此时,下载脚本已经开发完毕,终于不用担心壁纸荒啦!点击阅读原文获取项目地址!

本文来自小莫扎特博客www.plusminustsuchi.com 提供

内容版权声明:以上内容均为转载,如有侵犯原作者请联系删除!