python實現(xiàn)壁紙批量下載代碼實例
項目地址:https://github.com/jrainlau/wallpaper-downloader
前言
好久沒有寫文章了,因為最近都在適應(yīng)新的崗位,以及利用閑暇時間學(xué)習(xí)python。這篇文章是最近的一個python學(xué)習(xí)階段性總結(jié),開發(fā)了一個爬蟲批量下載某壁紙網(wǎng)站的高清壁紙。
注意:本文所屬項目僅用于python學(xué)習(xí),嚴禁作為其他用途使用!
初始化項目
項目使用了virtualenv
來創(chuàng)建一個虛擬環(huán)境,避免污染全局。使用pip3
直接下載即可:
pip3 install virtualenv
然后在合適的地方新建一個wallpaper-downloader
目錄,使用virtualenv
創(chuàng)建名為venv
的虛擬環(huán)境:
virtualenv venv . venv/bin/activate
接下來創(chuàng)建依賴目錄:
echo bs4 lxml requests > requirements.txt
最后yun下載安裝依賴即可:
pip3 install -r requirements.txt
分析爬蟲工作步驟
為了簡單起見,我們直接進入分類為“aero”的壁紙列表頁:http://wallpaperswide.com/aer...。
可以看到,這一頁里面一共有10張可供下載的壁紙。但是由于這里顯示的都是縮略圖,作為壁紙來說清晰度是遠遠不夠的,所以我們需要進入壁紙詳情頁,去找到高清的下載鏈接。從第一張壁紙點進去,可以看到一個新的頁面:
因為我機器是Retina屏幕,所以我打算直接下載體積最大的那個以保證高清(紅圈所示體積)。
了解了具體的步驟以后,就是通過開發(fā)者工具找到對應(yīng)的dom節(jié)點,提取相應(yīng)的url即可,這個過程就不再展開了,讀者自行嘗試即可,下面進入編碼部分。
訪問頁面
新建一個download.py
文件,然后引入兩個庫:
from bs4 import BeautifulSoup import requests
接下來,編寫一個專門用于訪問url,然后返回頁面html的函數(shù):
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
為了防止被網(wǎng)站反爬機制擊中,所以我們需要通過在header添加UA把爬蟲偽裝成正常的瀏覽器,然后指定utf-8編碼,最后返回字符串格式的html。
提取鏈接
在獲取了頁面的html以后,就需要提取這個頁面壁紙列表所對應(yīng)的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
這個函數(shù)會把列表頁所有壁紙詳情的url給提取出來。
下載壁紙
有了詳情頁的地址以后,我們就可以進去挑選合適的size了。在對頁面的dom結(jié)構(gòu)分析后可以知道,每一個size都對應(yīng)著一個鏈接:
所以第一步,就是把這些size對應(yīng)的鏈接提取出來:
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
就是對應(yīng)size的下載鏈接,接下來只需要通過requests
庫把鏈接的資源下載下來即可:
result = requests.get(PAGE_DOMAIN + biggest_one['url']) if result.status_code == 200: open('wallpapers/' + biggest_one['name'], 'wb').write(result.content)
注意,首先你需要在根目錄下創(chuàng)建一個wallpapers
目錄,否則運行時會報錯。
整理一下,完整的download_wallpaper
函數(shù)長這樣:
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)
批量運行
上述的步驟僅僅能夠下載第一個壁紙列表頁的第一張壁紙。如果我們想下載多個列表頁的全部壁紙,我們就需要循環(huán)調(diào)用這些方法。首先我們定義幾個常量:
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()
這里通過獲取命令行參數(shù),指定了三個常量category
, page_start
和page_end
,分別對應(yīng)著壁紙分類,起始頁頁碼,終止頁頁碼。
為了方便起見,再定義兩個url相關(guān)的常量:
PAGE_DOMAIN = 'http://wallpaperswide.com' PAGE_URL = 'http://wallpaperswide.com/' + category + '-desktop-wallpapers/page/'
接下來就可以愉快地進行批量操作了,在此之前我們來定義一個start()
啟動函數(shù):
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
函數(shù)再改寫一下:
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()
最后指定一下啟動規(guī)則:
if __name__ == '__main__': start()
運行項目
在命令行輸入如下代碼開始測試:
python3 download.py aero 1 2
然后可以看到下列輸出:
拿charles抓一下包,可以看到正在腳本正在平穩(wěn)地運行中:
此時,下載腳本已經(jīng)開發(fā)完畢,終于不用擔(dān)心壁紙荒啦!
以上就是本次為大家整理的全部內(nèi)容,大家有任何疑問可以在下方的留言區(qū)討論,感謝你對腳本之家的支持。
相關(guān)文章
python pandas cumsum求累計次數(shù)的用法
這篇文章主要介紹了python pandas cumsum求累計次數(shù)的用法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07何用Python實現(xiàn)一個 “系統(tǒng)聲音” 的實時律動掛件
這篇文章將給大家介紹了如何用 Python 實現(xiàn)一個 “系統(tǒng)聲音” 的實時律動掛件,采集后直接實時地在電腦上繪制波形動畫,主要是用來作為 FL Studio 播放時的一個桌面小掛件,文中有相關(guān)的代碼示例供大家參考,需要的朋友可以參考下2024-01-01Python數(shù)據(jù)處理之savetxt()和loadtxt()使用詳解
這篇文章主要介紹了Python數(shù)據(jù)處理之savetxt()和loadtxt()使用詳解,NumPy提供了多種存取數(shù)組內(nèi)容的文件操作函數(shù),保存數(shù)組數(shù)據(jù)的文件可以是二進制格式或者文本格式,今天我們來看看savetxt()和loadtxt()的用法,需要的朋友可以參考下2023-08-08