
import requests import json import os import re import time # 新增用于控制请求延迟 # 1. 关键从浏览器复制完整的 Cookie 和 Headers headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36 QQBrowser/21.1.8717.400, Referer: https://haokan.baidu.com/tab/shehui_new, # 关键完整的Cookie字符串从浏览器F12复制 Cookie: newlogin1; BDUSSEJGZWFBdmdtbEQtRGl6dDg0TzYyR0JybnpxRUdyZHpqeGxxUW91SUZ6RERMMFZxSVFBQUFBJCQAAAAAAAAAAAEAAABr5UEVUVFfMjgyNjE1MTA5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMOiHWrDoh1qc; BDUSS_BFESSEJGZWFBdmdtbEQtRGl6dDg0TzYyR0JybnpxRUdyZHpqeGxxUW91SUZ6RERMMFZxSVFBQUFBJCQAAAAAAAAAAAEAAABr5UEVUVFfMjgyNjE1MTA5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMOiHWrDoh1qc; BAIDUID12B658EA09C12D0BD5154700ABB7E735:FG1; BIDUPSID12B658EA09C12D0BD5154700ABB7E735; PSTM1780626218; BDORZFFFB88E999055A3F8A630C64834BD6D0; BAIDUID_BFESS12B658EA09C12D0BD5154700ABB7E735:FG1; __bid_n19eb62214d03728183c387; BA_HECTOR052lakal25a18581a5ag840la58kak1l2v7le28; ZFYz4dlRWO:Bw01rXjTUYWYrECWhYzyaYFQVwF7:Bq:BLHaw4:C; H_WISE_SIDS63147_67862_68166_69006_69295_69590_70116_70620_70544_70552_70504_70908_70916_70940_70946_70966_71000_71036_71049_71056_71062_71079_71086_71105; arialoadDatafalse; Hm_lvt_4aadd610dfd2f5972f1efee2653a2bc51781515173,1781569200; HMACCOUNTF22D314F8316F7B4; BDRCVFR[S_ukKV6dOkf]mk3SLVN4HKm; H_PS_PSSID63147_67862_68166_69006_69295_69590_70116_70620_70544_70552_70504_70908_70916_70940_70946_70966_71000_71036_71049_71056_71062_71079_71086_71105; delPer0; PSINO7; Hm_lpvt_4aadd610dfd2f5972f1efee2653a2bc51781577926; RTz1dmbaidu.comsiecd26d73-65c9-4559-96c4-0780df5f2c16ssmqfziekosl0tt0bcnhttps%3A%2F%2Ffclog.baidu.com%2Flog%2Fweirwood%3Ftype%3Dperf; ab_sr1.0.1_YTEyOTAzZDJlYTdmNzc4YjE1NThkN2Q0YzczYjI4MzBlNDZlNmI3NjA5NzlhMTlkMGEzNzdhMDJlYTU3MTBiMWRjNTkxODc5NmViMDk2Y2ZjMjJhZjU5ZWFlZjJjOTZlZmE4YmMwZjNiODZlYTJiZjNhZjZhMmI2YjlkYWI1ODUyZGQ5NmFkYTdiYTY2ZmQ3NjA4ZTEwZDliY2MxYzBhNw; reptileData%7B%22data%22%3A%22149ab658c534ce73cd3179424b269745ac8bf0fad4b939c7f732f0e8fa8d9f071bb53711903bf0c4aa4d177e07366edc2f066cab1154887aae07117d2e9ebbcda037c1dcb39786b2c4b843ce3a8a209e2b1b89bf3a7129453a4a8739a2fd9b44%22%2C%22key_id%22%3A%2230%22%2C%22sign%22%3A%22eeb28a8d%22%7D } # 2. 使用Session保持连接池 session requests.Session() session.headers.update(headers) # 新增函数获取指定页的视频 def get_videos_by_page(page1, num_per_page20): 获取指定页的视频数据 Args: page: 页码从1开始 num_per_page: 每页视频数量 Returns: list: 视频列表如果失败返回空列表 # 添加pn参数控制页码 url fhttps://haokan.baidu.com/haokan/ui-web/video/rec?tabshehui_newactpcFeedpdpcnum{num_per_page}pn{page} try: resp session.get(url, timeout5) data resp.json() # 检查返回状态 if data.get(status) ! 0: print(f第{page}页数据获取失败状态码: {data.get(status)}) return [] videos data.get(data, {}).get(response, {}).get(videos, []) print(f第{page}页获取到 {len(videos)} 个视频) return videos except Exception as e: print(f第{page}页请求失败: {e}) return [] # 新增函数结束 # 以下是原始代码保留 # 3. 发送请求极速- 原始单页代码现在改为使用函数 # url https://haokan.baidu.com/haokan/ui-web/video/rec?tabshehui_newactpcFeedpdpcnum20 # resp session.get(url, timeout5) # 4. 解析数据 - 原始代码现在改为使用函数 # data resp.json() # videos data[data][response][videos] # print(f获取到 {len(videos)} 个视频) # 创建文件夹 - 保留 if not os.path.exists(视频): os.makedirs(视频) # 现在的内容应该和网页一致了 - 保留注释 # for video in videos[:5]: # print(f标题: {video[title]}) # print(f播放: {video[play_url]}\n) # for video in videos: # # print(f链接: {video[play_url]}\n) # URL video[play_url] # # print(f链接: {URL}\n) # # resp1 requests.get(URL) # 原始代码结束 # 新增主函数批量翻页下载 def main(): 主函数控制批量翻页和下载流程 print( * 50) print(好看视频批量翻页下载工具) print( * 50) # 用户配置 try: total_pages int(input(请输入要下载的页数1-10页建议不超过5页: )) total_pages max(1, min(10, total_pages)) # 限制在1-10页 except ValueError: total_pages 2 print(f输入无效默认下载 {total_pages} 页) num_per_page 20 # 每页视频数量 all_videos [] # 存储所有视频 # 逐页获取视频列表 print(f\n开始获取视频列表共 {total_pages} 页...) for page in range(1, total_pages 1): videos get_videos_by_page(page, num_per_page) if not videos: print(f第{page}页没有获取到视频停止翻页) break all_videos.extend(videos) # 添加延迟避免请求过快 if page total_pages: print(f等待1秒后获取第{page 1}页...) time.sleep(1) # 统计结果 total_videos len(all_videos) print(f\n总计获取到 {total_videos} 个视频) if total_videos 0: print(没有获取到任何视频程序结束) return # 询问是否下载 choice input(f\n是否开始下载这 {total_videos} 个视频(y/n默认y): ).strip().lower() if choice and choice ! y: print(已取消下载) return # 原始下载逻辑保留并优化 print(f\n开始下载 {total_videos} 个视频...\n) success_count 0 fail_count 0 for i, video in enumerate(all_videos): # 获取视频信息 - 与原始代码一致 bt video.get(title, f未命名视频_{i}) # 标题 title re.sub(r[\\/*?:|], , bt) # 去除非法字符 - 原始代码 img video.get(poster_big, ) # 预览图地址 preview_img re.sub(r\u0026, , img) # 如果标题为空生成备用文件名 if not title: title fvideo_{i} URL video.get(play_url, ) # 获取播放链接 - 与原始代码一致 # print(f视频标题: {title}) # print(f播放链接: {URL}) # print(f预览图链接: {preview_img}\n\n) # 检查是否有播放链接 if not URL: print(f❌ [{i 1}/{total_videos}] {title} - 无播放链接跳过) fail_count 1 continue print(f\n\n[{i 1}/{total_videos}] 正在下载: {title}) print(f视频标题: {title}) print(f播放链接: {URL}) print(f预览图: {preview_img}) try: # 下载视频 - 与原始代码类似但添加了状态码检查和流式下载 video_resp session.get(URL, streamTrue, timeout30) # 检查响应状态码 if video_resp.status_code 200: file_path f视频/{title}.mp4 # 检查文件是否已存在 if os.path.exists(file_path): print(f⚠️ 文件已存在跳过: {title}.mp4) continue # 分块写入文件 - 优化大视频下载 with open(file_path, modewb) as f: for chunk in video_resp.iter_content(chunk_size8192): if chunk: f.write(chunk) # 获取文件大小 file_size os.path.getsize(file_path) print(f✅ {title}.mp4 下载完成! 大小: {file_size / 1024 / 1024:.2f} MB) success_count 1 else: print(f❌ 下载失败: {title}, 状态码: {video_resp.status_code}) fail_count 1 except requests.exceptions.Timeout: print(f❌ 下载超时: {title}) fail_count 1 except requests.exceptions.RequestException as e: print(f❌ 下载出错: {title}, 错误: {e}) fail_count 1 except Exception as e: print(f❌ 文件保存失败: {title}, 错误: {e}) fail_count 1 # 每个视频下载后短暂延迟避免被封IP if i total_videos - 1: time.sleep(0.5) # 统计下载结果 print(\n * 50) print(f下载完成成功: {success_count}个失败: {fail_count}个) print( * 50) # 新增主函数结束 # 原始代码保留 # if data[status] 0: # for video in videos: # t video[title] # title re.sub(r[\\/*?:|], , t) # URL video[play_url] # resp1 session.get(URL) # 直接使用URL不要循环 # # # 创建用于保存视频的文件夹 # # with open(f视频/{title}.mp4, modewb) as f: # f.write(resp1.content) # print(f{title}.mp4下载完成!) # 原始代码结束 # 程序入口 if __name__ __main__: main()