从Bunny.NET拉取视频自动发布到Squarespace的Python脚本报错求助
批量同步Bunny.net视频到Squarespace的脚本错误排查与修复
问题背景
需要将数百个视频从Bunny.NET Stream同步到Squarespace,生成带预览和直接下载链接的竖屏视频网格,手动操作效率低,编写Python脚本后运行报错。
报错信息
Traceback (most recent call last): File "C:\Users\ervin\AppData\Local\Programs\Python\Python312\Lib\site-packages\requests\models.py", line 971, in json return complexjson.loads(self.text, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\ervin\AppData\Local\Programs\Python\Python312\Lib\json\__init__.py", line 346, in loads return _default_decoder.decode(s) ^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\ervin\AppData\Local\Programs\Python\Python312\Lib\json\decoder.py", line 337, in decode obj, end = self.raw_decode(s, idx=_w(s, 0).end()) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\ervin\AppData\Local\Programs\Python\Python312\Lib\json\decoder.py", line 355, in raw_decode raise JSONDecodeError("Expecting value", s, err.value) from None json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) During handling of the above exception, another exception occurred: Traceback (most recent call last): File "C:\Users\ervin\Desktop\publish_videos.py", line 60, in <module> main() File "C:\Users\ervin\Desktop\publish_videos.py", line 48, in main bunny_video_ids = fetch_all_video_ids(bunny_api_key) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\ervin\Desktop\publish_videos.py", line 8, in fetch_all_video_ids return [video['id'] for video in response.json()['videos']] ^^^^^^^^^^^^^^^ File "C:\Users\ervin\AppData\Local\Programs\Python\Python312\Lib\site-packages\requests\models.py", line 975, in json raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
原脚本代码
import requests # Function to fetch all video IDs from Bunny.net def fetch_all_video_ids(api_key): url = 'https://api.bunny.net/videos' headers = {'AccessKey': api_key} response = requests.get(url, headers=headers) return [video['id'] for video in response.json()['videos']] # Function to fetch video details from Bunny.net def fetch_video_details(video_id, api_key): url = f'https://api.bunny.net/video/{video_id}/details' headers = {'AccessKey': api_key} response = requests.get(url, headers=headers) return response.json() # Function to publish video grid on Squarespace def publish_video_grid_on_squarespace(video_details_list, squarespace_api_key, page_id): # Creating HTML for video grid video_grid_html = '<div class="video-grid">' for video_details in video_details_list: video_url = video_details['url'] download_url = video_details['downloadUrl'] video_grid_html += f'<div class="video-wrapper">' video_grid_html += f'<video src="{video_url}" controls>' video_grid_html += f'<a href="{download_url}" download>Download Video</a></video>' video_grid_html += '</div>' video_grid_html += '</div>' # Publishing video grid on Squarespace url = f'https://api.squarespace.com/1.0/{page_id}/collections' headers = {'Authorization': f'Bearer {squarespace_api_key}'} data = { 'type': 'html', 'html': video_grid_html } response = requests.post(url, headers=headers, json=data) return response.json() # Main function def main(): # Set up your Bunny.net and Squarespace API credentials bunny_api_key = 'xxx' squarespace_api_key = 'xxx' squarespace_page_id = 'xxx' # Fetching all video IDs from Bunny.net bunny_video_ids = fetch_all_video_ids(bunny_api_key) # Fetching video details for each video and publishing video grid on Squarespace video_details_list = [] for video_id in bunny_video_ids: video_details = fetch_video_details(video_id, bunny_api_key) video_details_list.append(video_details) response = publish_video_grid_on_squarespace(video_details_list, squarespace_api_key, squarespace_page_id) print("Video grid published on Squarespace:", response) if __name__ == "__main__": main()
错误原因与修复方案
1. Bunny.net API端点错误(核心问题)
原脚本使用的Bunny API URL不符合官方规范:
- 视频列表API需要指定Library ID,正确端点为
https://api.bunny.net/stream/{LIBRARY_ID}/videos - 视频详情API同样需要Library ID,正确端点为
https://api.bunny.net/stream/{LIBRARY_ID}/video/{VIDEO_GUID} - 原URL返回非JSON内容(如404/403页面),导致JSON解析失败
2. 响应未做错误校验
未检查HTTP响应状态码,即使请求失败(如密钥无效、权限不足)仍尝试解析JSON,引发错误。
3. Squarespace API调用错误
原脚本使用的/collections端点不适合更新页面内容,正确的页面内容更新端点为https://api.squarespace.com/1.0/pages/{PAGE_ID},需用PUT请求而非POST。
4. HTML结构错误
<video>标签内不能嵌套<a>标签,需将下载链接移到video外部,保证HTML有效性。
修复后的脚本示例
import requests def fetch_all_video_ids(api_key, library_id): url = f'https://api.bunny.net/stream/{library_id}/videos' headers = {'AccessKey': api_key} response = requests.get(url, headers=headers) response.raise_for_status() # 自动抛出HTTP错误 # Bunny返回的视频列表在items数组中,唯一标识为guid return [video['guid'] for video in response.json()['items']] def fetch_video_details(video_guid, api_key, library_id): url = f'https://api.bunny.net/stream/{library_id}/video/{video_guid}' headers = {'AccessKey': api_key} response = requests.get(url, headers=headers) response.raise_for_status() video_data = response.json() # 整理所需字段:预览地址和下载地址 return { 'preview_url': video_data['playbackUrl'], 'download_url': f"https://video.bunnycdn.com/{library_id}/{video_guid}/download.mp4" } def publish_video_grid_on_squarespace(video_details_list, squarespace_api_key, page_id): # 修复HTML结构:下载链接放在video外部,添加基础样式 video_grid_html = '<div class="video-grid" style="display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 20px;">' for video in video_details_list: video_grid_html += f''' <div class="video-wrapper"> <video src="{video['preview_url']}" controls style="width: 100%; height: auto;"></video> <a href="{video['download_url']}" download style="display: block; margin-top: 10px; text-align: center;">下载视频</a> </div> ''' video_grid_html += '</div>' # 修正Squarespace API调用:更新页面内容 url = f'https://api.squarespace.com/1.0/pages/{page_id}' headers = { 'Authorization': f'Bearer {squarespace_api_key}', 'Content-Type': 'application/json' } # 替换页面的HTML区块内容,实际需根据页面结构调整 data = { 'sections': [ { 'type': 'html', 'html': video_grid_html } ] } response = requests.put(url, headers=headers, json=data) response.raise_for_status() return response.json() def main(): # 替换为实际的凭据 bunny_api_key = 'YOUR_BUNNY_API_KEY' bunny_library_id = 'YOUR_BUNNY_LIBRARY_ID' squarespace_api_key = 'YOUR_SQUARESPACE_API_KEY' squarespace_page_id = 'YOUR_SQUARESPACE_PAGE_ID' try: bunny_video_guids = fetch_all_video_ids(bunny_api_key, bunny_library_id) video_details_list = [] for guid in bunny_video_guids: details = fetch_video_details(guid, bunny_api_key, bunny_library_id) video_details_list.append(details) response = publish_video_grid_on_squarespace(video_details_list, squarespace_api_key, squarespace_page_id) print("视频网格已发布到Squarespace:", response) except Exception as e: print("执行出错:", str(e)) if __name__ == "__main__": main()
额外注意事项
- 确保Bunny API密钥拥有对应Library的读取权限
- Squarespace API需要开启权限,且页面ID需正确获取(可通过Squarespace开发者工具或API查询)
- 若视频数量较多,建议添加分页逻辑(Bunny API默认返回20条,可通过
page参数分页) - 可添加速率限制,避免触发API调用频率限制
内容的提问来源于stack exchange,提问作者Ervins Puksts
相关产品推荐
相关产品推荐

