编程学习网 > 编程语言 > Python > Python 爬虫:批量爬点男生喜欢的高清图片,顺手把几个坑踩一遍
2026
09-17

Python 爬虫:批量爬点男生喜欢的高清图片,顺手把几个坑踩一遍


图片爬虫最烦的不是把图片下载下来。

真正麻烦的是:跑半天存了一堆缩略图、重复图、404,最后目录里还混着几个几十 KB 的小图。

所以我写图片下载脚本时,一般不直接对网页里的 <img> 标签开抓。能走公开 API 就走 API,数据干净,图片尺寸、文件类型这些信息也能直接拿到。

这次抓点我自己平时会存的壁纸:汽车、机械、赛博朋克。

直接上 Python

先装一个依赖:

pip install requests

Wallhaven 有公开的搜索 API,普通 SFW 图片不需要 API Key,搜索接口能直接返回图片地址、分辨率、文件大小等信息。

我先写个最小版本试接口:

import requests
api = "https://wallhaven.cc/api/v1/search"
params = {
    "q": "sports car",
    "purity": "100",
    "sorting": "favorites",
    "atleast": "1920x1080"
}
resp = requests.get(api, params=params, timeout=10)
resp.raise_for_status()
for item in resp.json()["data"][:5]:
    print(item["resolution"], item["path"])

第一次写爬虫,我一般先停在这里。

别一上来就 while 循环跑几十页。先确认接口返回的数据是不是自己想要的,不然脚本吭哧吭哧下载半小时,最后发现拿到的全是小图,那就挺冤。

接口通了,再开始落盘。

我把下载部分单独拆出来:

from pathlib import Path
import hashlib
import requests
SAVE_DIR = Path("wallpaper_box")
SAVE_DIR.mkdir(exist_ok=True)
session = requests.Session()
session.headers.update({
    "User-Agent": "WallpaperCollector/1.0"
})

def save_picture(url, tag):
    r = session.get(url, timeout=20)
    r.raise_for_status()
    body = r.content
    # 太小的文件我直接不要
    if len(body) < 200 * 1024:
        print("skip small:", url)
        return
    digest = hashlib.md5(body).hexdigest()
    suffix = ".png" if "png" in r.headers.get("Content-Type", "") else ".jpg"
    file_path = SAVE_DIR / f"{tag}_{digest[:12]}{suffix}"
    if file_path.exists():
        print("skip repeat:", file_path.name)
        return
    file_path.write_bytes(body)
    print("saved:", file_path.name)

这里我没有直接拿图片原文件名保存。

图片站上的名字经常没什么意义,而且多关键词抓取以后可能重复。直接对内容算一个 MD5,既能当文件名,也顺手解决一部分重复下载的问题。

接下来把搜索和分页补上。

Wallhaven 的搜索结果是分页返回的,每页最多 24 条,所以分页别自己瞎猜,直接读返回结果里的 meta

import time
SEARCH_API = "https://wallhaven.cc/api/v1/search"

def collect(keyword, pages=2):
    for page in range(1, pages + 1):
        params = {
            "q": keyword,
            "categories": "100",
            "purity": "100",
            "sorting": "favorites",
            "order": "desc",
            "atleast": "1920x1080",
            "page": page
        }
        try:
            r = session.get(SEARCH_API, params=params, timeout=12)
            r.raise_for_status()
            payload = r.json()
        except requests.RequestException as exc:
            print(f"[{keyword}] page={page} request failed: {exc}")
            continue
        pictures = payload.get("data", [])
        print(f"[{keyword}] page={page}, found={len(pictures)}")
        for pic in pictures:
            width = pic.get("dimension_x", 0)
            height = pic.get("dimension_y", 0)
            if width < 1920 or height < 1080:
                continue
            try:
                save_picture(pic["path"], keyword.replace(" ", "_"))
            except requests.RequestException as exc:
                print("download failed:", exc)
            time.sleep(0.4)
        time.sleep(1)

这里两个 sleep 我一般会留着。

爬虫不是越快越牛。尤其是这种公共服务,你本地 20 个线程一起狠狠干,对自己没什么收益,对别人服务器倒挺有压力。

最后把关键词放进去:

topics = [
    "sports car",
    "motorcycle",
    "cyberpunk city",
    "mechanical keyboard"
]
for topic in topics:
    collect(topic, pages=2)

跑起来以后目录大概就是这种:

wallpaper_box/
├── sports_car_18bb42aa130e.jpg
├── sports_car_a28d7195be31.jpg
├── motorcycle_2fbe77de0df1.jpg
├── cyberpunk_city_692ac6af20e1.jpg
└── mechanical_keyboard_a122f91bce20.jpg

图片爬虫做到这里其实已经够用了。

我反而不建议急着上多线程。

图片下载属于 IO 操作,并发确实能提速,但只要线程数一开大,429、超时、连接重置这些东西马上就来了。最后代码里全是重试和限速,原本几十行能解决的事情,硬生生写成一个下载框架。

还有一个地方得注意。

这里我把 purity 固定成了 100,也就是只搜 SFW 内容。官方文档里 NSFW 内容需要有效 API Key,我这个脚本压根没必要碰。

真拿这个脚本自己玩,关键词比代码重要。

比如:

sports car
racing
motorcycle
space
cyberpunk city
mechanical keyboard
coding setup
samurai
mountains
aircraft

换一批关键词,就是另一套图库。

后面如果还想继续折腾,可以再加一个 Pillow,对下载后的图片做二次筛选,比如只保留横屏图:

from PIL import Image

def is_desktop_wallpaper(path):
    with Image.open(path) as img:
        w, h = img.size
        return w / h >= 1.6 and w >= 1920

这种过滤我觉得比再多爬一万张有用。

图片脚本最后拼的不是下载速度,而是留下来的东西干不干净。

请求接口、筛尺寸、做去重、控制频率、失败继续跑,这几个地方处理好,一个几十行的 Python 脚本,平时给电脑换壁纸已经完全够了。

另外,图片能下载不等于可以随便商用。自己学习、整理壁纸和拿图片做网站、公众号配图是两回事,后者最好再确认原图版权和授权信息。Wallhaven API 的搜索、分页和 SFW 过滤规则以官方文档为准。

以上就是“Python 爬虫:批量爬点男生喜欢的高清图片,顺手把几个坑踩一遍的详细内容,想要了解更多Python教程欢迎持续关注编程学习网。 

扫码二维码 获取免费视频学习资料

Python编程学习

查 看2022高级编程视频教程免费获取