python爬虫-好看视频网站-完整版带翻页代码2
·
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': 'newlogin=1; BDUSS=EJGZWFBdmdtbEQtRGl6dDg0TzYyR0JybnpxRUdyZHpqeGxxUW91SUZ6RERMMFZxSVFBQUFBJCQAAAAAAAAAAAEAAABr5UEVUVFfMjgyNjE1MTA5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMOiHWrDoh1qc; BDUSS_BFESS=EJGZWFBdmdtbEQtRGl6dDg0TzYyR0JybnpxRUdyZHpqeGxxUW91SUZ6RERMMFZxSVFBQUFBJCQAAAAAAAAAAAEAAABr5UEVUVFfMjgyNjE1MTA5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMOiHWrDoh1qc; BAIDUID=12B658EA09C12D0BD5154700ABB7E735:FG=1; BIDUPSID=12B658EA09C12D0BD5154700ABB7E735; PSTM=1780626218; BDORZ=FFFB88E999055A3F8A630C64834BD6D0; BAIDUID_BFESS=12B658EA09C12D0BD5154700ABB7E735:FG=1; __bid_n=19eb62214d03728183c387; BA_HECTOR=052lakal25a18581a5ag840la58kak1l2v7le28; ZFY=z4dlRWO:Bw01rXjTUYWYrECWhYzyaYFQVwF7:Bq:BLHaw4:C; H_WISE_SIDS=63147_67862_68166_69006_69295_69590_70116_70620_70544_70552_70504_70908_70916_70940_70946_70966_71000_71036_71049_71056_71062_71079_71086_71105; arialoadData=false; Hm_lvt_4aadd610dfd2f5972f1efee2653a2bc5=1781515173,1781569200; HMACCOUNT=F22D314F8316F7B4; BDRCVFR[S_ukKV6dOkf]=mk3SLVN4HKm; H_PS_PSSID=63147_67862_68166_69006_69295_69590_70116_70620_70544_70552_70504_70908_70916_70940_70946_70966_71000_71036_71049_71056_71062_71079_71086_71105; delPer=0; PSINO=7; Hm_lpvt_4aadd610dfd2f5972f1efee2653a2bc5=1781577926; RT="z=1&dm=baidu.com&si=ecd26d73-65c9-4559-96c4-0780df5f2c16&ss=mqfzieko&sl=0&tt=0&bcn=https%3A%2F%2Ffclog.baidu.com%2Flog%2Fweirwood%3Ftype%3Dperf"; ab_sr=1.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(page=1, num_per_page=20):
"""
获取指定页的视频数据
Args:
page: 页码,从1开始
num_per_page: 每页视频数量
Returns:
list: 视频列表,如果失败返回空列表
"""
# 添加pn参数控制页码
url = f'https://haokan.baidu.com/haokan/ui-web/video/rec?tab=shehui_new&act=pcFeed&pd=pc&num={num_per_page}&pn={page}'
try:
resp = session.get(url, timeout=5)
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?tab=shehui_new&act=pcFeed&pd=pc&num=20'
# resp = session.get(url, timeout=5)
# 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 = f"video_{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, stream=True, timeout=30)
# 检查响应状态码
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, mode='wb') as f:
for chunk in video_resp.iter_content(chunk_size=8192):
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', mode='wb') as f:
# f.write(resp1.content)
# print(f"{title}.mp4下载完成!")
# ========== 原始代码结束 ==========
# 程序入口
if __name__ == "__main__":
main()
更多推荐
所有评论(0)