吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 8298|回复: 18
收起左侧

[Python 原创] 【Python】无限制爬取Wallhaven壁纸网站源码&技术教学

  [复制链接]
ARtcgb 发表于 2021-4-23 16:08
本帖最后由 ARtcgb 于 2021-4-23 20:34 编辑

Python爬取Wallhaven壁纸站

之前看到论坛上已经有人发过这个壁纸站的爬虫,甚至还做了用户界面。所以我这个帖就不注重于代码了,而是注重于技术上面。
目标网址:wallhaven.cc

工具需求

第三方库:requests BeautifulSoup
展示操作环境:macOS Big Sur + Chrome + Python3.8

目标剖析 & 过程拆解

壁纸网站的爬虫和平常的爬虫其实没有什么区别,有些地方甚至还更简单。因为只要是你浏览器上显示的东西,爬虫都可以爬下来,壁纸网站的话就更好办了。

老规矩先看看F12,network刷新一下,看见img里面全是图片啊,这不就完事了?但是先观察一下,这些图片画质没有原图那么清晰,还不完整,都被切割成了300x200的缩略图。但是能发现,这些图片的名字有些奇怪,都是六位的字母+数字,回到HTML里面看一下,发现每个子页面的链接都是wallhaven.cc/w/ + 刚才缩略图的六位字母+数字构成的,还是传统的下载站布局。那就好说了。

wallhaven壁纸网站说白了还是个下载站的框架,和之前的套路一样,先从大的展示主页里面获取子页面的链接,再从子页面里面下载。这里下载图片需要用到写入文件的知识。

开始堆代码

观察下网页,我决定从toplist里面爬取壁纸,网站筛选菜单里有几个选项可以选,分别是General/Anime/People,生草翻译一下就是常规/二次元/三次元,看个人喜好自行选择;还有两个就是SFW/Sketchy,第一个就是safe for work,工作看很安全,嗯,那第二个就是工作时看会出事(确信

正常的toplist网址是这样的:https://wallhaven.cc/toplist
修改完几个选项之后就变成了这样:https://wallhaven.cc/search?categories=111&purity=110&topRange=1M&sorting=toplist&order=desc
但是把选项改回去和正常的选项一样,他的网址却回不去了:https://wallhaven.cc/search?categories=110&purity=100&topRange=1M&sorting=toplist&order=desc
这里面categories和purity的值发生了变化,多试几次发现分别和上面的几个选项有关。

选项 categories purity
General SFW 100 100
General Anime SFW 110 100
Anime SFW 010 100
Anime People SFW 011 100

到这里可以确定categories每位都受一个前面的选项影响,选择就是1,不选择就是0。现在试一下purity。

选项 categories purity
General SFW 100 100
General Sketchy 110 010
General SFW  Sketchy 100 110

写到这里我已经流鼻血了,网站链接就说这么多了,现在开始爬!

为了方便演示,源码中出现的网址为toplist的标准短链接形式,自定义爬虫时可替换,不会影响代码执行。

先request请求下来看看吧,这里用最普通的get请求就可以了,别忘了做个假的UA放到header里面。

import requests

headers = {'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.137 Safari/4E423F'}
# 随便写的
html = "https://wallhaven.cc/toplist"
requests_html = requests.get(html, headers=headers)
print(requests_html.text)

HTML代码已经到手,很简单,现在该考虑解析了。F12里面看下我们需要的东西在哪里,不要被预览图所在的位置所迷惑,找到我们需要的链接在哪里就可以了。 <a class="preview">

拿出我们的老朋友BeautifulSoup,提取<a class="preview">的href值。

Soup_all = BeautifulSoup(requests_html.text, 'lxml').find_all("a", class_="preview")
for Soup in Soup_all:
        print(Soup['href'])

完事,换个方式把这些链接存到list里面,方便一会儿挨个爬取。

url_list = []
for Soup in BeautifulSoup(requests_html.text, 'lxml').find_all("a", class_="preview"):
        url_list.append(Soup['href'])

下面来看看单页。

更简单,图片链接直接在<img id="wallpaper">的src属性里面了,没有任何隐瞒。直接写代码。

num = 0
for link in url_list:
    requests_html = requests.get(link, headers=headers)
    bs_html = BeautifulSoup(requests_html.text, "lxml")
    img = bs_html.find('img', id='wallpaper')
    r = requests.get(img['src'])
                num += 1
    with open("/Users/artcgb/Downloads/壁纸/+ str(num) + ".jpg", 'wb') as f:
        f.write(r.content)

用上Python的读写文件操作,直接就可以写入图片,十分方便全程毫无尿点。缺点就是如果文件名一样,新鞋入的图片会覆盖之前的,所以我优化了下代码,让他每天爬的时候都新建一个文件夹存储,这样就不会覆盖掉了。

源代码

import requests
from bs4 import BeautifulSoup
import os
import datetime

now = str(datetime.datetime.today().date())
# 获取当前日期

headers = {'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.137 Safari/4E423F'}

num = 0
url_list = []
for page in range(1, 6):
    html1 = "https://wallhaven.cc/latest?page=" + str(page)
    html2 = "https://wallhaven.cc/hot?page=" + str(page)
    html_list = [html1, html2]
    for html in html_list:
        requests_html = requests.get(html, headers=headers)

        bs_html = BeautifulSoup(requests_html.text, "lxml")

        for link in bs_html.find_all('a', class_="preview"):
            image_link = link['href']
            url_list.append(image_link)
            num += 1
            print("已获取第" + str(num) + "个链接")

a = os.path.exists("/Users/artcgb/Downloads/壁纸/" + now)
if a:
    print("文件夹已存在,PASS")
else:
    os.mkdir("/Users/artcgb/Downloads/壁纸/" + now)
    print("文件夹建立成功")
# 建立文件夹存放图片
num = 0
for link in url_list:
    requests_html = requests.get(link, headers=headers)
    bs_html = BeautifulSoup(requests_html.text, "lxml")
    img = bs_html.find('img', id='wallpaper')
    r = requests.get(img['src'])
    num += 1
    with open("/Users/artcgb/Downloads/壁纸/" + now + "/" + str(num) + ".jpg", 'wb') as f:
        f.write(r.content) 
        print("第" + str(num) + "张写入成功")

免费评分

参与人数 6吾爱币 +9 热心值 +6 收起 理由
x827770484 + 1 我很赞同!
DavisC + 1 + 1 用心讨论,共获提升!
eyesstworld + 1 + 1 我很赞同!
fxone + 1 + 1 谢谢@Thanks!
苏紫方璇 + 5 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
三笙三世 + 1 + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

JMILOVEYOU 发表于 2022-3-30 20:52
Wallhaven的精髓就是注册账号 点开NSFW专区
ibetty 发表于 2021-4-23 16:50
dseqrasd 发表于 2021-4-23 17:02
Luckyu920 发表于 2021-4-23 17:26
本帖最后由 Luckyu920 于 2021-4-23 17:31 编辑

open("/Users/artcgb/Downloads/壁纸/+ str(num)" + ".jpg", 'wb')


这个地方写错了

应该是

open("/Users/artcgb/Downloads/壁纸/" + str(num) + ".jpg", 'wb')
Luckyu920 发表于 2021-4-23 17:30
Luckyu920 发表于 2021-4-23 17:26
open("/Users/artcgb/Downloads/壁纸/+ str(num)" + ".jpg", 'wb')

而且,忘记把now加进去了

最终应该是
[Python] 纯文本查看 复制代码
open("/Users/artcgb/Downloads/壁纸/" + now + "/" + str(num) + ".jpg", 'wb')
鬼将军温宁 发表于 2021-4-23 17:32
感谢楼主分享的好东西
x827770484 发表于 2021-4-23 17:40
我这个运行之后报了个看不懂的错,我丢人了....
QQ截图20210423173919.png
 楼主| ARtcgb 发表于 2021-4-23 18:17
Luckyu920 发表于 2021-4-23 17:30
而且,忘记把now加进去了

最终应该是

对的,代码复制进来删了些东西,忘了复查一遍,谢谢
 楼主| ARtcgb 发表于 2021-4-23 18:18
x827770484 发表于 2021-4-23 17:40
我这个运行之后报了个看不懂的错,我丢人了....

不知道啊,我没报过这样的错,看起来可能是因为请求太频繁被封IP了
mll9308 发表于 2021-4-23 18:47
爬的壁纸都会覆盖。。。不重命名始终只有一张
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 06:44

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表