python 微博爬虫 01

起因, 目的:

  • ✅下载单个视频,完成。
  • ✅ 获取某用户的视频列表,完成。
  • 剩下的就是, 根据视频列表,逐个下载视频,我没做,没意思。
  • 获取视频的评论,以后再说。

关键点记录:

1. 对一个视频的直接 url,

  • ssig 是变动的。 我估计是有时效的。
  • 使用 requests 来下载单独视频,还是可行的。

2. 获取视频播放列表

  • 不能直接使用 seleinum 库, 因为网页没有显示,只能一个一个点击。 会很慢.
  • 获取视频播放列表,可以访问 api: https://weibo.com/ajax/profile/getWaterFallContent?uid=5653796775&cursor=4436755690237089
  • cursor 参数是从 0 开始,而且相应的json 中,会给出 “next_cursor”: “4560020807617171”
  • 实际情况是,使用 firefox 浏览器查看 json 相应,很方便查看 json 的结构,很清晰。

3. 爬取微博,不建议使用 requests 库, 理由是

  • 静态页面和动态页面的区别。
  • 中间有个 js 验证!

1. 使用 requests,单独下载一个微博视频, 成功。

# -*- coding: UTF-8 -*-
import requests# 1. 假如知道了视频的直接 url, 那么直接下载视频,成功!
# 2. 知道了视频的 主页面,然后找到视频的 url, 再下载。失败! 因为中间涉及 js !def make_headers():headers = {'Accept-Encoding': '*/*','Referer': 'https://weibo.com/','User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36',}return headersclass PlayAround:def __init__(self):self.headers = make_headers()self.session = requests.Session()self.fail = []# 单纯的下载视频。已经完成。能实现。def download_video(self, video_url, video_name):resp = self.session.get(video_url, headers=self.headers,  allow_redirects=False)if resp.status_code == 200:with  open(f"{video_name}.mp4", "wb") as f:f.write(resp.content)if __name__ == '__main__':p = PlayAround()# 视频的直接链接mp4_url = "https://f.video.weibocdn.com/o0/QSQkAf0wlx08cD50PfXa01041201cfbq0E010.mp4?label=mp4_1080p&template=1080x1920.24.0&media_id=5002705307893807&tp=8x8A3El:YTkl0eM8&us=0&ori=1&bf=4&ot=v&lp=00002D9dZv&ps=mZ6WB&uid=6Ak7kf&ab=13038-g1,,8012-g2,3601-g32,3601-g31,8013-g0,3601-g29,3601-g39,3601-g19,3601-g36,3601-g27,12739-g1,3601-g38,3601-g37&Expires=1744548301&ssig=jh4Js32Fx1&KID=unistore,video"video_name = "赵露思的微博的微博视频223"p.download_video(mp4_url, video_name)

2. 使用 selenuim + cookies 登录微博

实际上,修改 cookies, 可以登录任意网站。

import time
import random
import json
import pickle
from selenium import webdriver
from selenium.webdriver.chrome.options import Options"""
此文件, 使用 selenium + cookies, 登录微博  1. 任意网站,从插件 editThisCookie 导出所有的 cookies , 复制到 cookies.json 文件
2. 运行此文件的过程中,会自动生成 pickle 文件
3. 然后模拟登录,刷新页面,即可登录成功
4. 继续 selenium 的其他功能如果报错,那么需要删除 cookies 中的 sameSite 属性, 并重新生成 pickle 文件
"""URL = "https://weibo.com/"
PKL_NAME = "weibo_cookies.pkl"
JSON_NAME =  "weibo_cookies.json"class SeleHeaders:def __init__(self):self.option = Options()# self.option.add_argument("--start-maximized")# self.option.add_argument('--headless')self.bot = webdriver.Chrome(options=self.option)@staticmethoddef make_cookie():with open(JSON_NAME, encoding="utf-8") as f:cookies = json.load(f)# 删除 sameSite 属性for c in cookies:if "sameSite" in c:del c["sameSite"]# 保存为 pickle 文件with open(PKL_NAME, "wb") as f:pickle.dump(cookies, f)print("✅ 已生成新的 pickle 文件(sameSite 属性已删除)")def login(self):self.make_cookie()bot = self.botbot.get(URL)time.sleep(random.randint(3, 7))try:cookies = pickle.load(open(PKL_NAME, "rb"))for c in cookies:bot.add_cookie(c)bot.refresh()print("✅ 登录成功!")# 刷新页面,检查效果!for i in range(3):time.sleep(random.randint(2, 5))bot.refresh()except Exception as e:print("❌ 失败!请检查 cookies 文件或登录状态")print(e)if __name__ == "__main__":meme = SeleHeaders()meme.login()
3. 使用 selenium 提取一个视频的基本信息
  • 比如: ‘2,095万次观看 · 1月前 · 发布于 四川’
  • 还是需要使用 cookies, 与前面的很像相似。
import os
import time
import random
import json
import pickle
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import requests"""
2025-04-13 19:07:07   能成功运行, 能下载视频。此文件, 
1. 使用 selenium + cookies, 登录 weibo.com
2. 找到视频的 url , 下载视频1. 任意网站,从插件 editThisCookie 导出所有的 cookies , 复制到 cookies.json 文件
2. 运行此文件的过程中,会自动生成 pickle 文件
3. 然后模拟登录,刷新页面,即可登录成功
4. 继续 selenium 的其他功能如果报错,那么需要删除 cookies 中的 sameSite 属性, 并重新生成 pickle 文件
"""URL = "https://weibo.com/"
PKL_NAME = "weibo_cookies.pkl"
JSON_NAME =  "weibo_cookies.json"def make_headers():headers = {'Accept-Encoding': '*/*','Referer': 'https://weibo.com/','User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36',}return headersdef make_cookies():if PKL_NAME in os.listdir(): return # 已有 pickle 文件,直接返回with open(JSON_NAME, encoding="utf-8") as f:cookies = json.load(f)# 删除 sameSite 属性for c in cookies:if "sameSite" in c:del c["sameSite"]# 保存为 pickle 文件with open(PKL_NAME, "wb") as f:pickle.dump(cookies, f)print("✅ 已生成新的 pickle 文件(sameSite 属性已删除)")class SeleniumSpider:def __init__(self):self.option = Options()# self.option.add_argument("--start-maximized")# self.option.add_argument('--headless')self.bot = webdriver.Chrome(options=self.option)make_cookies()def login(self):bot = self.botbot.get(URL)time.sleep(random.randint(3, 7))try:cookies = pickle.load(open(PKL_NAME, "rb"))for c in cookies:bot.add_cookie(c)bot.refresh()print("✅ 登录成功!")except Exception as e:print("❌ 失败!请检查 cookies 文件或登录状态")print(e)def get_video_info(self, url):video_info = {"video_url": "","video_name": "","video_date": ""}bot = self.botbot.get(url)time.sleep(random.randint(3, 6))  # Wait for page to load# Check if URL is a direct video linkif url.endswith(('.mp4', '.m3u8')):video_info["video_url"] = urlvideo_info["video_name"] = url.split('/')[-1].split('.')[0]print(f"✅ 检测到直接视频链接: {url}")else:# Parse page for video informationtry:# Find video elementvideo_element = bot.find_element("tag name", "video")video_info["video_url"] = video_element.get_attribute("src")except:print(f"❌ 未找到视频元素: {url}")return None# Extract title (video name)try:video_info["video_name"] = bot.title.strip()except:video_info["video_name"] = f"weibo_video_{int(time.time())}"print(f"⚠️ 未找到标题,使用默认名称: {video_info['video_name']}")# Extract full date/views/location stringtry:# Target div.star-f16 with parent div.Detail_tith4_3_UzS# '2,095万次观看 · 1月前 · 发布于 四川'date_element = bot.find_element("css selector", "div.Detail_tith4_3_UzS > div.star-f16")#date_element = bot.find_element("css selector", "div.Detail_tith4_3_UzS")video_info["video_date"] = date_element.text.strip()except:video_info["video_date"] = ""print("⚠️ 未找到日期信息")print(f"✅ 获取视频信息成功: {url}")print(video_info)return video_infodef download_video(self, video_info, save_path=""):session = requests.Session()headers =  make_headers()# Construct full save pathfilename = f"{video_info['video_name']}.mp4"# Download videoprint(f"⏳ 开始下载: {filename}")response = session.get(video_info["video_url"], headers=headers, stream=True, timeout=30)if response.status_code == 200:with open(filename, "wb") as f:for chunk in response.iter_content(chunk_size=8192):if chunk:f.write(chunk)print(f"✅ 下载成功: {filename}")return Trueelse:print(f"❌ 下载失败: {filename} (状态码: {response.status_code})")return Falseif __name__ == "__main__":# 1. 先登录spider = SeleniumSpider()spider.login()# 2. 再获取视频的内容one_video_url = "https://weibo.com/tv/show/1034:5136658249744436?mid=5136667216183574"video_info = spider.get_video_info(one_video_url)# 3. 下载视频if video_info:spider.download_video(video_info, save_path="videos/")spider.bot.quit()  # Close browser when done

输出结果:
在这里插入图片描述

4. 使用 requests + cookies + api, 获取某用户的视频播放列表。
  • 这部分是比较麻烦的。需要加上 cookies!! 否则的话,得到的是 js 代码 !
  • 下面的代码,请使用自己的 cookies ,并且修改页数,默认是5页。
import requests# 请求 api: https://weibo.com/ajax/profile/getWaterFallContent?uid=5653796775&cursor=4436755690237089
# 这里有点复杂,需要加上 cookies!!
# 否则的话,会得到 js !
def make_headers():headers = {'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7','Referer': 'https://weibo.com/','User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36',"cookie": "SC*****很长很长*******FVH4X16"}return headers# def get_video_list(self, user_id, max_pages=5):
def get_video_list( user_id, max_pages=5):# api: https://weibo.com/ajax/profile/getWaterFallContent?uid=5653796775&cursor=4436755690237089video_infos = []cursor = "0"cnt = 0for page in range(max_pages):print(f"⏳ 获取第 {page + 1} 页视频...")url = f"https://weibo.com/ajax/profile/getWaterFallContent?uid={user_id}&cursor={cursor}"response = requests.get(url, headers=make_headers())print(response.status_code)print(response.text)if response.status_code != 200:print(f"❌ API 请求失败: {response.status_code}")breakdata = response.json()print(type(data))# 解析 JSON 数据for item in data.get("data", {}).get("list", []):# 此时位于 data/list/item[0]# 继续提取 page_info/media_info/playback_list/[0]/play_info/url# 对于 playback_list, 只需要提前第一个即可。playback_list = item.get("page_info", {}).get("media_info", {}).get("playback_list", [])for play_info in playback_list:video_url = play_info.get("play_info", {}).get("url", "")print(video_url)print(play_info)print()cnt += 1break# 继续检查下一个 api jsoncursor = data.get("data", {}).get("next_cursor", "")if not cursor:print("✅ 已到达最后一页")breakprint(f"✅ 共收集 {cnt} 个视频信息")return video_infosif __name__ == '__main__':get_video_list(user_id="5653796775", max_pages=5)

输出效果类似:
在这里插入图片描述

结论 + todo

  1. 就是找点事情做做。不然很无聊。
  2. 微博爬虫,估计会继续。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/76724.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Servlet、HTTP与Spring Boot Web全面解析与整合指南

目录 第一部分:HTTP协议与Servlet基础 1. HTTP协议核心知识 2. Servlet核心机制 第二部分:Spring Boot Web深度整合 1. Spring Boot Web架构 2. 创建Spring Boot Web应用 3. 控制器开发实践 4. 请求与响应处理 第三部分:高级特性与最…

vue中根据html动态渲染内容2.0

上次使用的是p标签用的contenteditable代替的可编辑的input,最后实现还是选择了用el-input的textarea方式。 一开始考虑的是需要根据用户输入自动撑开输入框,所以选择了p标签可编辑。 最后发现还是el-input会更好一点,只不过需要处理输入框撑…

CentOS 系统磁盘扩容并挂载到根目录(/)的详细步骤

在使用 CentOS 系统时,经常会遇到需要扩展磁盘空间的情况。例如,当虚拟机的磁盘空间不足时,可以通过增加磁盘容量并将其挂载到根目录(/)来解决。以下是一个完整的操作流程,详细介绍了如何将新增的 10G 磁盘…

LINUX基础 [二] - Linux常见指令

目录 💻前言 💻指令 🎮ls指令 🎮pwd指令 🎮whoami指令 🎮cd指令 🎮clear指令 🎮touch指令 🎮mkdir指令 🎮rmdir指令 🎮rm指令 &#…

基于php的成绩分析和预警与预测网站(源码+lw+部署文档+讲解),源码可白嫖!

摘要 人类现已迈入二十一世纪,科学技术日新月异,经济、资讯等各方面都有了非常大的进步,尤其是资讯与网络技术的飞速发展,对政治、经济、军事、文化、教育等各方面都有了极大的影响。 利用电脑网络的这些便利,发展一套…

《从底层逻辑剖析:分布式软总线与传统计算机硬件总线的深度对话》

在科技飞速发展的当下,我们正见证着计算机技术领域的深刻变革。计算机总线作为信息传输的关键枢纽,其发展历程承载着技术演进的脉络。从传统计算机硬件总线到如今备受瞩目的分布式软总线,每一次的变革都为计算机系统性能与应用拓展带来了质的…

Spring Boot 3.5新特性解析:自动配置再升级,微服务开发更高效

📝 摘要 Spring Boot 3.5作为Spring生态的最新版本,带来了多项令人振奋的改进。本文将深入解析其中最核心的自动配置增强特性,以及它们如何显著提升微服务开发效率。通过详细的代码示例和通俗易懂的讲解,您将全面了解这些新特性在…

【前端】webpack一本通

今日更新完毕,不定期补充,建议关注收藏点赞。 目录 简介Loader和Plugin的不同?(必会) 使用webpack默认只能处理js文件 ->引入加载器对JS语法降级,兼容低版本语法合并文件再次打包进阶 工作原理Webpack 的…

leetcode 264. Ugly Number II

动态规划解决。 关键是理解如何生成新的丑数。这道题和经典的斐波那契数列问题其实是一样的。求第n个数,需要用第n个数前面的数来求。不同的是,斐波那契数列不会重复。而本题的丑数,会重复出现。 class Solution { public:int nthUglyNumbe…

深入理解 HTML5 语义元素:提升网页结构与可访问性

引言 在构建网页的过程中,合理的结构与清晰的语义对于网页的质量、可维护性以及搜索引擎优化(SEO)都至关重要。HTML5 引入了一系列语义元素,为开发者提供了更精准描述网页内容的工具。本文将深入探讨 HTML5 语义元素的作用、使用…

PyCharm显示主菜单和工具栏

显示主菜单 新版 PyCharm 是不显示主菜单的,要想显示主菜单和工具栏,则通过 “视图” → “外观” ,勾选 “在单独的工具栏中显示主菜单” 和 “工具栏” 即可。 设置工具栏 此时工具栏里并没有什么工具,因此我们需要自定义工具…

CyclicBarrier 基本用法

CyclicBarrier 基本用法 简介 CyclicBarrier 是 Java 并发包(java.util.concurrent)中的一个同步辅助类。它允许一组线程相互等待,直到到达某个公共屏障点(common barrier point)。只有当所有参与的线程都到达屏障点…

[特殊字符] 手机连接车机热点并使用 `iperf3` 测试网络性能

好的,以下是根据你的描述整理出来的步骤及解释: 📶 手机连接车机热点并使用 iperf3 测试网络性能 本文将通过 iperf3 来测试手机和车机之间的网络连接性能。我们会让车机作为服务端,手机作为客户端,进行 UDP 流量传输…

FPGA上实现SD卡连续多块读的命令

在FPGA上实现SD卡连续多块读的命令 CMD17命令一次只能读取1个块 CMD18命令一次可以连续读取多个块,直到停止命令CMD12 CMD18命令读的块数程序可任意设置 目录 前言 一、SD卡多块读命令CMD18 二、停止读命令CMD12 三、SD卡初始化SD卡连续块读操作的verilog代码 …

DeepSeek 助力 Vue3 开发:打造丝滑的日历(Calendar)

前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏关注哦 💕 目录 Deep…

NSGA-II 多目标优化 —— 理论、案例与交互式 GUI 实现

目录 NSGA-II 多目标优化 —— 理论、案例与交互式 GUI 实现一、引言二、NSGA-II 基本原理2.1 非支配排序2.2 拥挤距离2.3 算法流程三、数学模型与算法推导3.1 多目标优化问题描述3.2 非支配关系与排序3.3 拥挤距离计算四、NSGA-II 的优缺点4.1 优点4.2 缺点五、典型案例分析5.…

库学习04——numpy

一、基本属性 二、 创建数组 (一)arange a np.arange(10,20,2) # [10,12,14,16,18] 只有一个参数n的话,默认是从0到n-1的一维数组。 (二)自定义reshape a np.arange(12).reshape((3,4)) [[ 0 1 2 3][ 4 5 …

NVIDIA Jetson 快速切换CUDA版本| 多CUDA版本

当NVIDIA Jetson中安装了多个CUDA时,可以通过命令,快速切换不同版本的。 这样在环境变量和代码编译时,能使用指定版本的CUDA了。 本文适用于Jetson Nano、TX1/TX2、Xavier 和 Orin系列的设备,供大家参考。 cuda参考地址&#xf…

当开源邂逅AI,公益长出翅膀 | 回顾3.30 上海「开源×AI 赋能公益」Meetup

在春和景明的三月,一场打破常规的公益聚会在上海剪爱公益发展中心肇清项目点温暖上演。这,便是G-Star公益行带来的「开源AI 赋能公益」Meetup,一场技术与善意交织、创新与温暖共生的奇妙之旅。 活动现场,没有高冷的技术壁垒&#…

高阶函数/柯里化/纯函数

本篇文章主要是介绍一下标题里面的概念,在面试的时候经常文档,结合阅读到的资料,结合本人的个人见解出品了该文章,如有写的不好的地方或理解有误的,还望阁下多多指教。 1、高阶函数 什么是高阶函数? 接受…