自动为图床添加图片

整个流程分为两步:

  1. 获取 Bing 每日图片:通过调用 Bing 的官方 API 获取当天壁纸的 URL。
  2. 上传到你的图床:将获取到的图片数据,通过你提供的 API 上传到你的图床。

由于这个操作需要每天自动执行,最好的方式是编写一个自动化脚本,并使用定时任务(如 GitHub Actions、Cron Job 等)来运行它。


核心思路

我们的脚本将执行以下操作:

  1. 向 Bing API 发送请求,获取包含图片信息的 JSON 数据。
  2. 从 JSON 中解析出图片的 URL。
  3. 下载这张图片到内存中。
  4. 构造一个 POST 请求,将图片数据上传到你的图床 API。
  5. (可选)记录上传成功的日志。

步骤一:编写 Python 自动化脚本

这是最核心的部分。我们需要 requests 库来处理网络请求。如果你的 Python 环境没有安装,请先执行 pip install requests

下面是一个完整的 Python 脚本 (sync_bing_wallpaper.py),你只需要修改顶部的配置信息即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
import requests
import datetime
import os
import sys # 引入sys模块来读取命令行参数

# --- 配置区 ---
# ... (你的图床域名和认证码配置保持不变)
YOUR_DOMAIN = ""
AUTH_CODE = ""
NASA_API_KEY = "" # 👈 在这里填入你的NASA API Key

UPLOAD_PARAMS = {
"authCode": AUTH_CODE,
"uploadNameType": "origin",
"returnFormat": "full",
}
# ... 上面读取环境变量的代码 ...

# ==========================================================
# 在这里添加下面这行代码 👇
# ==========================================================
# 根据你的域名构造上传API的完整URL
upload_url = f"https://your domain/upload"

# ... 你脚本的其他部分,比如函数定义 ...

# --- 图片获取函数区 ---
# ... (get_bing_wallpaper, get_nasa_apod, get_wallhaven_random 三个函数放在这里) ...
# 在你的脚本中再添加这个函数
def get_wallhaven_random():
"""从Wallhaven获取一张随机壁纸"""
# API文档: https://wallhaven.cc/help/api
# 这里我们获取一张随机的、SFW (Safe for Work) 的图片
wallhaven_api_url = "https://wallhaven.cc/api/v1/search"
params = {
"sorting": "random", # 随机排序
"purity": "100", # 100 表示 SFW, 010 SFW+Sketchy, 001 NSFW
}
try:
print("正在请求 Wallhaven API...")
response = requests.get(wallhaven_api_url, params=params, timeout=15)
response.raise_for_status()

data = response.json()

if not data.get("data"):
print("错误:Wallhaven API 未返回任何图片。")
return None, None

# 获取第一张图片的信息
image_info = data["data"][0]
image_url = image_info["path"] # Wallhaven直接提供完整URL
image_id = image_info["id"]
filename = f"wallhaven-{image_id}.jpg" # 用ID命名防止重复

print(f"成功获取到Wallhaven随机壁纸: {filename}")
print(f"图片地址: {image_url}")

# 下载图片内容
print("正在下载图片...")
image_response = requests.get(image_url, timeout=60)
image_response.raise_for_status()

return filename, image_response.content

except requests.exceptions.RequestException as e:
print(f"错误:获取Wallhaven壁纸失败: {e}")
return None, None

# 在你的脚本中添加这个新函数
def get_nasa_apod(api_key):
"""获取NASA每日天文图的URL和数据"""
apod_api_url = "https://api.nasa.gov/planetary/apod"
params = {
"api_key": api_key
}
try:
print("正在请求 NASA APOD API...")
response = requests.get(apod_api_url, params=params, timeout=15)
response.raise_for_status()

data = response.json()

# NASA APOD 有时会发布视频,我们需要确保是图片
if data.get("media_type") != "image":
print(f"今日NASA内容不是图片,而是 {data.get('media_type')},跳过。")
return None, None

# 优先获取高清图 'hdurl',如果不存在则用普通 'url'
image_url = data.get("hdurl", data.get("url"))
if not image_url:
print("错误:在NASA API响应中未找到图片URL。")
return None, None

# 使用图片的标题作为文件名,如果标题不存在,用日期
title = data.get("title", f"nasa_apod_{datetime.date.today().strftime('%Y-%m-%d')}")
# 清理文件名中不适合的字符
filename = "".join(x for x in title if x.isalnum() or x in " .-_").strip() + ".jpg"

print(f"成功获取到今日NASA天文图: {filename}")
print(f"图片地址: {image_url}")

# 下载图片内容
print("正在下载图片...")
image_response = requests.get(image_url, timeout=60)
image_response.raise_for_status()

return filename, image_response.content

except requests.exceptions.RequestException as e:
print(f"错误:获取NASA APOD失败: {e}")
return None, None

def get_bing_wallpaper():
"""获取Bing每日壁纸的URL和数据"""
try:
# Bing API,mkt=zh-CN表示获取中国区的壁纸
bing_api_url = "https://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1&mkt=zh-CN"
print("正在请求 Bing API...")
response = requests.get(bing_api_url, timeout=10)
response.raise_for_status() # 如果请求失败则抛出异常

data = response.json()
image_info = data["images"][0]

# 1. 构造完整的图片URL
relative_url = image_info["url"]
full_image_url = f"https://www.bing.com{relative_url}"

# 2. 从URL中提取一个合适的文件名
# 例如: 从 /th?id=OHR.UshguliGeorgia_ZH-CN9379665389_1920x1080.jpg&rf=LaDigue_1920x1080.jpg&pid=hp
# 提取出 OHR.UshguliGeorgia_ZH-CN9379665389_1920x1080.jpg
try:
filename = image_info['urlbase'].split('.')[-1] + '.jpg'
filename = os.path.basename(image_info['url']).split('&')[0].replace('th?id=', '')
except Exception:
# 如果解析失败,使用日期作为文件名
filename = f"bing_{datetime.date.today().strftime('%Y-%m-%d')}.jpg"

print(f"成功获取到今日壁纸信息: {filename}")
print(f"图片地址: {full_image_url}")

# 3. 下载图片内容
print("正在下载图片...")
image_response = requests.get(full_image_url, timeout=30)
image_response.raise_for_status()

return filename, image_response.content

except requests.exceptions.RequestException as e:
print(f"错误:获取Bing壁纸失败: {e}")
return None, None

def upload_to_your_bed(filename, image_data):
"""上传图片到你的图床"""
if not filename or not image_data:
print("没有可上传的图片数据,任务中断。")
return

upload_url = f"{YOUR_DOMAIN}/upload"
files = {
'file': (filename, image_data, 'image/jpeg')
}

try:
print(f"正在上传图片到: {upload_url}")
response = requests.post(upload_url, params=UPLOAD_PARAMS, files=files, timeout=60)
response.raise_for_status()

response_data = response.json()

# 根据你的API响应格式,提取链接
if response_data and isinstance(response_data, list) and "src" in response_data[0]:
image_url = response_data[0]["src"]
# 如果返回的是相对路径,拼接成完整URL
if not image_url.startswith('http'):
final_url = f"{YOUR_DOMAIN}{image_url}"
else:
final_url = image_url

print("🎉 上传成功!")
print(f"图片链接: {final_url}")
else:
print(f"错误:上传成功,但响应格式不正确: {response.text}")

except requests.exceptions.RequestException as e:
print(f"错误:上传图片失败: {e}")
if 'response' in locals():
print(f"服务器响应: {response.text}")
# --- 上传函数区 ---
# ... (upload_to_your_bed 函数保持不变) ...
# 将 def upload_to_your_bed(filename, image_data):
# 修改为:
# sync_bing_wallpaper.py

# ... 其他代码 ...

# 请将你的整个函数替换成这个正确的版本 👇
# sync_bing_wallpaper.py

# ... 其他代码 ...

# 请将你的整个函数替换成这个最终正确的版本 👇
def upload_to_your_bed(img_filename, img_data, params):
"""根据API文档,上传图片到图床"""
print(f"正在上传 {img_filename} 到图床...")
try:
# 修正1: 根据API文档,文件参数名应为 'file'
files = {'file': (img_filename, img_data)}

# 使用修正后的 upload_url 和 files 字典发送请求
response = requests.post(upload_url, params=params, files=files, timeout=60)

# 检查HTTP请求是否成功 (例如 4xx 或 5xx 错误)
response.raise_for_status()

# 修正2: 根据API文档解析响应
# 响应是一个列表,如: [{"src": "/file/abc.jpg"}]
result = response.json()

if isinstance(result, list) and len(result) > 0 and 'src' in result[0]:
# API返回的是相对路径,我们需要自己拼接成完整URL
relative_path = result[0]['src']
full_url = f"https://{YOUR_DOMAIN.strip('/')}{relative_path}"
print(f"上传成功!图片URL: {full_url}")
return full_url
else:
# 如果API返回的格式不符合预期
print(f"上传失败,API返回了非预期的格式: {result}")
return None

except requests.exceptions.HTTPError as e:
# 更详细地打印HTTP错误,比如405, 401等
print(f"上传失败,HTTP错误: {e}")
print(f"响应内容: {e.response.text}")
return None
except requests.exceptions.RequestException as e:
print(f"上传请求失败: {e}")
return None
except Exception as e:
print(f"处理上传时发生未知错误: {e}")
return None

# ... 你脚本的其余部分 ...

# --- 主程序入口 ---
if __name__ == "__main__":

# 允许通过命令行参数选择来源,例如: python your_script.py bing
# 默认来源是 bing
source = "bing"
if len(sys.argv) > 1:
source = sys.argv[1] # 获取第一个命令行参数作为来源

print(f"--- 开始同步 [{source}] 图片 [{datetime.datetime.now()}] ---")

img_filename, img_data = None, None
upload_folder = source # 默认以上传源命名文件夹

if source == "bing":
img_filename, img_data = get_bing_wallpaper()
upload_folder = "bing"
elif source == "nasa":
if not NASA_API_KEY or NASA_API_KEY == "YOUR_NASA_API_KEY":
print("错误:请先在脚本中配置你的 NASA_API_KEY。")
else:
img_filename, img_data = get_nasa_apod(NASA_API_KEY)
upload_folder = "nasa_apod"
elif source == "wallhaven":
img_filename, img_data = get_wallhaven_random()
upload_folder = "wallhaven"
else:
print(f"错误:未知的图片来源 '{source}'。可用来源: bing, nasa, wallhaven")

# 如果成功获取到图片,就上传
if img_filename and img_data:
# 动态设置上传目录
current_upload_params = UPLOAD_PARAMS.copy()
current_upload_params["uploadFolder"] = upload_folder
upload_to_your_bed(img_filename, img_data, current_upload_params) # 修改一下上传函数,让它接收params

print("--- 任务结束 ---")

使用说明:

  1. 将上面代码保存为 sync_bing_wallpaper.py 文件。

  2. 修改配置:打开文件,将 YOUR_DOMAINAUTH_CODE 以及 _NASA_API_KEY_替换成你自己的信息。UPLOAD_PARAMS 中的参数也可以根据你的需求调整。

    • 修改 YOUR_DOMAIN: 将 "https://your.domain" 替换成你图床的真实、可访问的域名例如,如果你的图床访问地址是 https://img.cool-pics.com,那么你应该修改为: YOUR_DOMAIN = "https://img.cool-pics.com"

    • 修改 AUTH_CODE: 将 "your_authCode" 替换成你图床API说明里提到的真实认证码例如,如果你的认证码是 abcdef123456,那么你应该修改为: AUTH_CODE = "abcdef123456" 如果你的图床不需要认证码,可以设置为空字符串: AUTH_CODE = ""

  3. 本地测试:在命令行中运行 python sync_bing_wallpaper.py,看看是否能成功上传并打印出图片链接。


步骤二:设置自动化每日执行

当脚本可以手动运行时,下一步就是让它每天自动运行。这里推荐两种最流行的方法:

方法一:使用 GitHub Actions (强烈推荐)

这种方法免费、稳定,不需要你自己的服务器。

  1. 创建 GitHub 仓库

    • 登录 GitHub,创建一个新的公开私有仓库。
    • 将你的 sync_bing_wallpaper.py 文件上传到这个仓库。
  2. 添加依赖文件

    • 在仓库根目录创建一个名为 requirements.txt 的文件,内容只有两行:
      1
      2
      3
            requests
      beautifulsoup4

  3. 创建 Workflow 文件

    • 在你的仓库页面,点击 “Actions” 标签页。
    • 点击 “set up a workflow yourself”(或者类似的按钮)。
    • 这会创建一个 .github/workflows/main.yml 文件。将文件名修改为更有意义的,比如 image_sync.yml。
    • 将文件内容替换为以下代码:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
     
    # .github/workflows/image_sync.yml

    name: Sync Daily Wallpapers

    # ===================================================================
    # 触发器 (Triggers)
    # ===================================================================
    on:
    schedule:
    - cron: '0 0 * * *' # 每天北京时间 8:00 (UTC 0:00)
    - cron: '0 1 * * *' # 每天北京时间 9:00 (UTC 1:00)
    - cron: '0 */6 * * *' # 每6小时

    workflow_dispatch:
    inputs:
    source:
    description: 'Image source to sync (bing, nasa, or wallhaven)'
    required: true
    default: 'bing'
    type: choice
    options:
    - bing
    - nasa
    - wallhaven

    # ===================================================================
    # 任务 (Jobs)
    # ===================================================================
    jobs:
    sync-images:
    # 在最新的 Ubuntu 环境上运行
    runs-on: ubuntu-latest

    # ===============================================================
    # 步骤 (Steps)
    # ===============================================================
    steps:
    # 步骤 1: 拉取代码
    - name: Checkout repository
    uses: actions/checkout@v4

    # 步骤 2: 设置 Python 环境
    - name: Set up Python 3.10
    uses: actions/setup-python@v5
    with:
    python-version: '3.10'

    # 步骤 3: 安装 Python 依赖库
    # 不需要 working-directory,因为 requirements.txt 就在根目录
    - name: Install dependencies
    run: |
    python -m pip install --upgrade pip
    pip install -r requirements.txt

    # 步骤 4: 执行同步脚本
    # 同样不需要 working-directory,因为 sync_bing_wallpaper.py 就在根目录
    - name: Run sync script
    env:
    YOUR_DOMAIN: ${{ secrets.YOUR_DOMAIN }}
    AUTH_CODE: ${{ secrets.AUTH_CODE }}
    NASA_API_KEY: ${{ secrets.NASA_API_KEY }}
    run: |
    # 打印当前工作目录和文件列表,用于最终确认
    echo "--- Current Directory: $(pwd) ---"
    echo "--- Files in Root: ---"
    ls -l
    echo "------------------------------------"

    # 根据不同的触发条件,执行不同的命令
    if [[ -n "${{ github.event.inputs.source }}" ]]; then
    echo "Running from MANUAL trigger. Source: ${{ github.event.inputs.source }}"
    python sync_bing_wallpaper.py ${{ github.event.inputs.source }}
    elif [[ "${{ github.event.schedule }}" == "0 0 * * *" ]]; then
    echo "Running from SCHEDULED trigger for Bing."
    python sync_bing_wallpaper.py bing
    elif [[ "${{ github.event.schedule }}" == "0 1 * * *" ]]; then
    echo "Running from SCHEDULED trigger for NASA."
    python sync_bing_wallpaper.py nasa
    elif [[ "${{ github.event.schedule }}" == "0 */6 * * *" ]]; then
    echo "Running from SCHEDULED trigger for Wallhaven."
    python sync_bing_wallpaper.py wallhaven
    else
    echo "Error: No matching trigger condition found."
    exit 1
    fi
  4. 配置 Secrets (重要!)

    • 不要将你的域名和认证码直接写在 Python 脚本里提交到 GitHub。我们使用 GitHub Secrets 来安全地存储它们。
    • 首先,在你的 GitHub 仓库页面,进入 Settings -> Secrets and variables -> Actions
    • 点击 New repository secret,创建三个 Secret:
      • Name: YOUR_DOMAIN
      • Value: https://your.domain (你的图床完整域名)
      • Name: AUTH_CODE
      • Value: your_authCode (你的认证码)
      • Name: NASA_API_KEY
  5. 完成

    • 现在,GitHub Actions 会在每天指定的时间自动运行你的脚本,从 Secrets 中获取配置,完成壁纸的同步。你可以在仓库的 “Actions” 标签页查看每次运行的日志。

方法二:使用 Linux Cron Job (如果你有自己的服务器)

  1. sync_bing_wallpaper.py 文件上传到你的服务器,例如放在 /home/user/scripts/ 目录下。

  2. 打开终端,输入 crontab -e 来编辑你的定时任务。

  3. 在文件末尾添加一行,格式如下:

    1
    2
    # 每天早上 8:05 执行脚本,并将日志输出到文件
    5 8 * * * /usr/bin/python3 /home/user/scripts/sync_bing_wallpaper.py >> /home/user/scripts/bing_sync.log 2>&1
    • 5 8 * * * 表示每天的 8:05 执行。
    • /usr/bin/python3 是你 Python 解释器的路径,可以通过 which python3 查看。
    • >> /home/user/scripts/bing_sync.log 2>&1 会将脚本的所有输出(包括错误)追加到日志文件中,方便排查问题。
  4. 保存并退出编辑器。系统会自动安排任务。


总结

  1. 准备脚本:使用上面提供的 Python 脚本,并填入你的配置信息。
  2. 选择自动化方式
    • 无服务器:首选 GitHub Actions,安全、方便、免费。
    • 有服务器:使用 Cron Job
  3. 设置并测试:按照上述步骤配置好自动化,并手动触发一次(或等待它自动运行)来验证整个流程是否通畅。

这样,你的图床就能每天自动拥有最新的 Bing 壁纸了!