🔹 引言
壁纸网站上有很多精美的高清图,但如果一个个手动保存,既耗时又麻烦。
今天我们用 Python 写一个完整的爬虫脚本,批量下载 城市分类下的高清壁纸,优先获取最大分辨率(8K/5K/4K),并自动保存到本地。
目标站点: https://backiee.com/categories/city
🔹 技术栈
-
Python 3.9+
-
requests:网络请求
-
BeautifulSoup4:HTML 解析
-
re:正则解析 ID 和分辨率
-
os / time:文件操作 & 下载限速
🔹 爬虫逻辑设计
-
获取总页数
-
解析分页信息
"Page 1 of 20"→ 得到总页数
-
-
获取详情页链接
-
遍历分页,提取所有壁纸详情页 URL
-
-
解析原图地址
-
从
<img src/srcset>或<a href>找到最大分辨率 -
若未找到 → 根据常见分辨率(8K/5K/4K…)+ 壁纸 ID 猜测原图直链
-
-
下载图片
-
自动重命名:
分辨率-文件名.jpg -
已存在则跳过,避免重复
-
-
限速保护
-
每次请求之间
time.sleep(0.1),避免触发反爬
-
import os
import re
import time
import requests
from bs4 import BeautifulSoup
from urllib.parse import urljoin
BASE_URL = "https://backiee.com/categories/city"
SITE = "https://backiee.com"
SAVE_DIR = "city_full"
os.makedirs(SAVE_DIR, exist_ok=True)
HEADERS = {
"User-Agent": (
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/115.0 Safari/537.36"
),
"Accept-Language": "en-US,en;q=0.9",
}
# 常见大尺寸(从大到小)
COMMON_RES = [
"7680x4320", # 8K
"5120x2880", # 5K
"3840x2160", # 4K
"3440x1440",
"2560x1600",
"2560x1440",
"2560x1080",
"1920x1200",
"1920x1080",
]
# 已知的缩略尺寸目录(全部剔除)
THUMB_RES = {"560x315", "336x189", "456x257"}
session = requests.Session()
session.headers.update(HEADERS)
session.timeout = 15
def get_total_pages():
r = session.get(BASE_URL)
r.raise_for_status()
soup = BeautifulSoup(r.text, "html.parser")
pager_text = soup.select_one(".pager-text").get_text(strip=True)
total = int(re.search(r"of (\d+)", pager_text).group(1))
return total
def get_detail_links(page: int):
url = f"{BASE_URL}?page={page}"
r = session.get(url)
r.raise_for_status()
soup = BeautifulSoup(r.text, "html.parser")
links = []
for a in soup.select(".col-sm-4.col-md-4 a[href*='/wallpaper/']"):
href = a.get("href")
if not href:
continue
links.append(href if href.startswith("http") else urljoin(SITE, href))
return sorted(set(links))
def parse_res_from_url(url: str):
# 解析 /static/wallpapers/{WxH}/{id}.jpg 里的 WxH
m = re.search(r"/static/wallpapers/(\d+x\d+)/", url)
if not m:
return None, 0
res = m.group(1)
try:
w, h = res.split("x")
area = int(w) * int(h)
except Exception:
return res, 0
return res, area
def is_valid_wallpaper_url(url: str):
if "/static/wallpapers/" not in url:
return False
res, _ = parse_res_from_url(url)
if not res:
return False
if res in THUMB_RES:
return False
if "placeholder" in url:
return False
return True
def best_from_detail_html(html: str):
soup = BeautifulSoup(html, "html.parser")
candidates = set()
# 1) img 的 src / srcset
for img in soup.select("img"):
src = img.get("src") or ""
srcset = img.get("srcset") or ""
if src:
candidates.add(src)
if srcset:
for part in srcset.split(","):
u = part.strip().split(" ")[0]
if u:
candidates.add(u)
# 2) a 标签可能直接给下载链接
for a in soup.select("a[href]"):
href = a.get("href") or ""
if href:
candidates.add(href)
# 归一化、过滤缩略图和无关资源
normalized = []
for u in candidates:
if not u.startswith("http"):
u = urljoin(SITE, u)
if is_valid_wallpaper_url(u):
res, area = parse_res_from_url(u)
normalized.append((area, res, u))
if not normalized:
return None
# 按分辨率面积从大到小选最大那张
normalized.sort(reverse=True, key=lambda x: x[0])
return normalized[0][2]
def probe_full_by_id(detail_url: str):
"""
如果页面没给原图直链,就用 id 猜测常见分辨率直链并探测。
观察到缩略图文件名经常是 id +/- 100000 的变体,所以一并尝试。
"""
m = re.search(r"/wallpaper/[^/]+/(\d+)", detail_url)
if not m:
return None
base_id = int(m.group(1))
id_candidates = [base_id, base_id + 100000, base_id + 200000]
for res in COMMON_RES:
for fid in id_candidates:
test_url = f"{SITE}/static/wallpapers/{res}/{fid}.jpg"
try:
# 用 GET 探测(有些站点对 HEAD 处理不一致)
resp = session.get(test_url, stream=True, timeout=10)
if resp.status_code == 200 and "image" in resp.headers.get("Content-Type", ""):
return test_url
except requests.RequestException:
pass
finally:
try:
resp.close()
except Exception:
pass
return None
def get_full_image(detail_url: str):
# 先用详情页 HTML 解析最大分辨率
r = session.get(detail_url)
r.raise_for_status()
# 优先从 HTML 提取分辨率最大的 /static/wallpapers/{WxH}/...jpg
best = best_from_detail_html(r.text)
if best:
return best
# 退而求其次:按常见分辨率 + id 探测直链
fallback = probe_full_by_id(detail_url)
return fallback
def safe_name(url: str):
clean_url = url.split("?")[0]
basename = os.path.basename(clean_url)
res, _ = parse_res_from_url(url)
prefix = f"{res}-" if res else ""
name = prefix + basename
# 清理非法字符
name = re.sub(r'[\\/*?:"<>|]', "_", name)
return name
def download_image(url: str):
name = safe_name(url)
path = os.path.join(SAVE_DIR, name)
if os.path.exists(path):
print(f"⏩ 已存在: {name}")
return
try:
with session.get(url, stream=True) as resp:
resp.raise_for_status()
with open(path, "wb") as f:
for chunk in resp.iter_content(chunk_size=1024 * 64):
if chunk:
f.write(chunk)
print(f"✅ 下载成功: {name}")
except Exception as e:
print(f"❌ 下载失败: {url} 错误: {e}")
def main():
total_pages = get_total_pages()
print(f"📄 共 {total_pages} 页")
# 先小范围测试
for p in range(1, total_pages + 1):
print(f"=== 正在处理第 {p} 页 ===")
links = get_detail_links(p)
print(f"🔍 找到 {len(links)} 个详情页链接")
for link in links:
full = get_full_image(link)
if full:
download_image(full)
else:
print(f"⚠️ 未找到原图: {link}")
time.sleep(0.1) # 轻微限速,避免过于频繁
print("完成前2页测试。确认无误后,把 range(4, 10) 改为 range(1, total_pages + 1) 跑全量。")
if __name__ == "__main__":
main()
# 🏙️ Backiee 壁纸爬虫
批量爬取 [Backiee](https://backiee.com) 网站的高清壁纸。
支持 **城市分类**(默认),可下载 **8K/5K/4K 壁纸**,自动选择最大分辨率并保存到本地。
---
## ⚙️ 功能特性
- ✅ 自动获取所有分页的壁纸详情页
- ✅ 解析详情页 HTML,提取最大分辨率原图
- ✅ 如果未找到直链,则尝试常见分辨率进行探测
- ✅ 自动重命名:`分辨率-文件名.jpg`
- ✅ 已下载的文件自动跳过(断点续传)
- ✅ 简单限速,防止过快触发反爬
---
## 📖 使用说明书
### 1. 环境准备
确保你已安装 Python 3.9+,并安装依赖库:
```bash
pip install requests beautifulsoup4
2. 使用方法
-
将爬虫代码保存为
backiee_spider.py -
在命令行运行:
-
程序会自动:
-
访问 Backiee 城市分类
-
遍历所有分页,解析详情页
-
下载最大分辨率壁纸
-
保存到
city_full文件夹
-
3. 参数说明
-
BASE_URL
壁纸分类页面,例如:如果要下载自然风景分类,可以改为:
-
SAVE_DIR
壁纸保存目录,例如: -
COMMON_RES
常见大分辨率,按顺序优先探测(8K → 5K → 4K → …)
4. 注意事项
-
脚本会自动跳过已下载的文件,支持断点续传
-
默认限速
0.1s,避免过快触发反爬 -
若网络不稳定,可能提示
❌ 下载失败,不会影响继续运行 -
请遵守目标网站的 Robots 协议 与使用规范
5. 常见问题
-
Q: 下载中断后能继续吗?
A: 可以,已存在的文件会自动跳过。 -
Q: 想下载其他分类怎么办?
A: 修改BASE_URL为对应分类地址,修改SAVE_DIR为保存目录。
💻 运行效果示例
执行后控制台输出:
最终壁纸会保存在:



小飞3 个月前
我从未见过一个强者拥有简单的过往。
一个人有超越年龄的沉稳,遇人遇事毫不慌乱,动作稳定,情绪稳定,承受打击能力强,应变迅速,都意味着这个人,曾有超越年龄的痛苦折磨。
遭遇过比面前更加重大的打击,且无人托底,独自爬起来,才能在危机和变故突然袭来时,面无表情的淡定,只寻找解决办法。
稳,多么残忍的一个字。