前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >爬虫简单实践之 wallhaven

爬虫简单实践之 wallhaven

作者头像
EmoryHuang
发布2022-10-31 15:43:13
5870
发布2022-10-31 15:43:13
举报
文章被收录于专栏:EmoryHuang's Blog

爬虫简单实践之 wallhaven

前言

闲来无事,简单写了一个爬虫,功能也很简单,就是爬取 wallhaven 上的图片。

阅读之前,如果你对爬虫感到陌生,你也可以点击 这里 在我的另一篇文章中快速、了解掌握爬虫。

爬虫思路

根据 url 的规律指定爬取页面

简单观察 url 便可以发现,规律很简单,只需要指定页面即可。

代码语言:javascript
复制
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 得到图片数据,然后写入文件即可,类似这样:

代码语言:javascript
复制
data = requests.get(url, headers=headers)
with open(img_name, 'wb') as f:
    f.write(data.content)

完整代码

代码语言:javascript
复制
'''
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


# 获得当前页面所有图片 url
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) + '页图片')
        # 获得当前页上所有图片的 url
        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

            # 解析得到图片原路径以及图片id
            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)

结语

对于其他的图片网站,我们也可以采取类似的方法下载图片,当然也可能遇到各种各样的问题,比如图片大小,网站验证等问题,这时候就要具体情况具体分析了吧。

练习之作,如有问题请指出。

相关文章

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-08-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 爬虫简单实践之 wallhaven
    • 前言
      • 爬虫思路
        • 根据 url 的规律指定爬取页面
        • 解析 html 获得当前页面所有图片 url
        • 进入图片之后,再次解析 html 获得原始图片的 url
        • get 原始图片的 url 并保存到本地
      • 完整代码
        • 结语
          • 相关文章
          相关产品与服务
          文件存储
          文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档