Python《wallhaven壁纸爬取》

今天不小心又发现了壁纸网站,感觉壁纸很多啊,多?我就忍不住了。爬一下咯。
我们今天爬取 网站是https://wallhaven.cc/。

先来分析分析:
进入首页:我们先去找标签,果然有个大标签地址链接。
在这里插入图片描述

点进去后发现:
在这里插入图片描述

一共有三层标签分类,第三层的标签就直接对应了很多的图片。
假如我们随便点击一个“anime girls”,我们发现他的标签号是5。
在这里插入图片描述

第一页呢只是几张图,但是有个按钮能看到更多,我们点进去。
在这里插入图片描述

发现url很有特点啊。q=tagId。我猜测这个q是query的意思。
后来经过测试,我们可以通过搜索自己输入的关键字,那时候q就是等于自己输入的关键字了。不过我们今天想从tag的角度来爬取网站。
往下翻一番,滑动下鼠标会发现,会出现page的分页标记。
在这里插入图片描述

%3A就是英文的冒号:。地址栏显示的时候就变成了%3A。

鼠标往下滑就是分页,而且在同一个页面展示,因此我们打开开发者模式的network去查看下XHR信息了。
在这里插入图片描述

好了,当我们确定;当我们得到个tagId,我们只需要去简单的添加page信息就可以得到完整的分页信息。

根据元素找到每一张图片,一般我们会先看到缩略图,点击缩略图后才能看到高清大图。
按照经验,一般而言,缩略图和高清图是存在某种直接的对应关系的,url存在规律的。
比如我们有缩略图:
在这里插入图片描述

所对应的高清图是:
在这里插入图片描述

再比如缩略图:
在这里插入图片描述

所对应的高清图是:
在这里插入图片描述

再比如缩略图:
在这里插入图片描述

所对应的高清图是:
在这里插入图片描述
发现确实存在规律哈
总结下就是得到如下规律:
在这里插入图片描述

好了分析完毕
完整代码如下:

import time
from concurrent.futures import ThreadPoolExecutor
import time
import os
import re
from urllib.parse import urlencode

import requests
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.chrome.options import  Options


rootrurl = 'https://wallhaven.cc/?'
searchUrl = 'https://wallhaven.cc/search?'
ImgUrl = 'https://w.wallhaven.cc/full/{}/wallhaven-{}'
save_dir = 'D:/estimages/'
headers = {
    "Referer": rootrurl,
    'User-Agent': "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36",
    'Accept-Language': 'en-US,en;q=0.8',
    'Cache-Control': 'max-age=0',
    'Connection': 'keep-alive'
}  ###设置请求的头部,伪装成浏览器

def saveOneImg(dir, img_url):
    new_headers = {
        "Referer": img_url,
        'User-Agent': "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36",
        'Accept-Language': 'en-US,en;q=0.8',
        'Cache-Control': 'max-age=0',
        'Connection': 'keep-alive'
    }  ###设置请求的头部,伪装成浏览器,实时换成新的 header 是为了防止403 http code问题,防止反盗链,

    try:
        img = requests.get(img_url, headers=new_headers)  # 请求图片的实际URL
        if (str(img).find('200') > 1):
            with open(
                    '{}/{}.jpg'.format(dir, img_url.split('/')[-1].split('?')[0]), 'wb') as jpg:  # 请求图片并写进去到本地文件
                jpg.write(img.content)
                print(img_url)
                jpg.close()
            return True
        else:
            return False
    except Exception as e:
        print('exception occurs: ' + img_url)
        print(e)
        return False



def processOnePages(tmpDir, imgs):
    for img in imgs:
        code = img.get('data-src').split('/')[-1]

        # 拼装高清大图的地址
        saveOneImg(tmpDir, ImgUrl.format(code[:2], code))
    pass


def oneSpiderProcess(name, tag):

    tmpDir = '{}/{}'.format(save_dir, name)
    if not os.path.exists(tmpDir):
        os.makedirs(tmpDir)

    page = 1
    while 1:
        params = {
            'q': tag,
            'page' : page
        }
        url = searchUrl + urlencode(params)
        print('current page is: %s' % url)
        html = BeautifulSoup(requests.get(url, headers=headers).text, features="html.parser")

        footer = html.find('footer', {'class': 'pagination-notice'})
        if footer is not None:
            break

        imgs = html.find('section', {'class': 'thumb-listing-page'}).find('ul').find_all('img')
        page = page + 1
        processOnePages(tmpDir, imgs)


def getAllTags():

    # 此处应该是从标签页面去获取很多的。为了演示,这里自己手动填写了几个演示一下
    list = {'初音未来': 'id:3', '最终幻想VII': 'id:2659', 'Uzumaki Naruto': 'id:1188'}
    return list


if __name__ == '__main__':
    taglist = getAllTags()

    # 给每个标签配备一个线程
    with ThreadPoolExecutor(max_workers=5) as t:  # 创建一个最大容纳数量为20的线程池
        for name, tag in taglist.items():
            t.submit(oneSpiderProcess, name, tag)

    # test one tag
    # oneSpiderProcess('初音未来', 'id:3')

    # 等待所有线程都完成。
    while 1:
        print('-------------------')
        time.sleep(1)

效果如下:

请添加图片描述

请添加图片描述
请添加图片描述

  • 7
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值