爬虫简单实践之 wallhaven
前言
闲来无事,简单写了一个爬虫,功能也很简单,就是爬取 wallhaven 上的图片。
阅读之前,如果你对爬虫感到陌生,你也可以点击 这里 在我的另一篇文章中快速、了解掌握爬虫。
爬虫思路
根据 url 的规律指定爬取页面
简单观察 url 便可以发现,规律很简单,只需要指定页面即可。
1
| https://wallhaven.cc/toplist?page=
|
解析 html 获得当前页面所有图片 url
接下来我们观察 html 结构
很显然,我们需要的链接在一个 a
标签中,且 class=preview
,那么,我们便可以通过 find_all('a', class_='preview')
命令找到所有的 url。
注意上面的另一个 url 是小图,如果你不关心图片尺寸,那么可以直接使用它。
进入图片之后,再次解析 html 获得原始图片的 url
得到图片的 url 之后,我们再次 get ,进入图片页面,再次解析 html,观察结构
同样的,我们发现原始图片的链接在一个 img
标签中,且 id=wallpaper
,链接在 src
之中,用类似的方法使用 BeautifulSoup
进行解析,这样,我们就得到了图片的 url。
另外,我们可以用 data-wallpaper-id
作为标识符,或者给图片命令。
get 原始图片的 url 并保存到本地
得到了原始图片的 url 后,我们便可以再次 get 得到图片数据,然后写入文件即可,类似这样:
1 2 3
| data = requests.get(url, headers=headers) with open(img_name, 'wb') as f: f.write(data.content)
|
完整代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
| ''' Descroption: wallhaven 爬虫 Author: EmoryHuang Date: 2021-08-25 11:10:33 Method: 1. 根据 url 的规律指定爬取页面 2. 解析 html 获得当前页面所有图片 url 3. 进入图片之后,再次解析 html 获得原始图片的 url 4. get 原始图片的 url 并保存到本地 '''
import os import sys import time import requests from typing import List from bs4 import BeautifulSoup
def get_page_url(page: str) -> List[str]: ''' :description: 获得当前页面所有图片 url :param {str} page 指定页号 :return {List[str]} 返回当前页面的图片 url 列表 ''' headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36', 'Connection': 'keep-alive' } url = 'https://wallhaven.cc/toplist?page=' + str(page) r = requests.get(url, headers=headers, timeout=5) soup = BeautifulSoup(r.text, 'lxml') page_url = [] for link in soup.find_all('a', class_='preview'): page_url.append(link.get('href')) return page_url
def download(path: str, start: int = 1, cnt: int = 5) -> None: ''' :description: 图片下载到本地 :param {str} path 文件存储路径 :param {int} start 起始页号,默认为1 :param {int} cnt 爬取页数,默认为5 :return {*} ''' print('开始爬取 wallhaven/toplist 图片第' + str(start) + '-' + str(start + cnt - 1) + '页') session = requests.Session() session.encoding = 'utf-8' headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36', 'Connection': 'keep-alive' }
for page in range(start, start + cnt): print('开始下载第' + str(page) + '页图片') page_url = get_page_url(page)
for i, pic_url in enumerate(page_url, 1): if os.path.exists(path + pic_url.split('/')[-1] + '.png'): print('第' + str(page) + '页, 第' + str(i) + '张图片已存在') continue
try: r = session.get(pic_url, headers=headers, timeout=5) soup = BeautifulSoup(r.text, 'lxml') except: print('第' + str(page) + '页, 第' + str(i) + '张图片请求失败') continue
img_tag = soup.find('img', id='wallpaper') img_id = img_tag.get('data-wallpaper-id') img_raw_url = img_tag.get('src') img_name = path + img_id + '.png'
try: data = session.get(img_raw_url, headers=headers, timeout=5) with open(img_name, 'wb') as f: f.write(data.content) f.flush() print('第' + str(page) + '页, 第' + str(i) + '张图片下载成功') except: print('第' + str(page) + '页, 第' + str(i) + '张图片下载失败') else: time.sleep(1)
print('第' + str(page) + '页图片下载完成') print('第' + str(start) + '-' + str(start + cnt - 1) + '页图片下载完成')
if __name__ == '__main__': cur_dir = os.path.dirname(sys.argv[0]) databse_dir = cur_dir + '\\wallhaven_download\\' if not os.path.exists(databse_dir): os.makedirs(databse_dir) download(databse_dir)
|
结语
对于其他的图片网站,我们也可以采取类似的方法下载图片,当然也可能遇到各种各样的问题,比如图片大小,网站验证等问题,这时候就要具体情况具体分析了吧。
练习之作,如有问题请指出。
相关文章