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.pswp.cn/bicheng/76724.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/76724.shtml
英文地址,請注明出處:http://en.pswp.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、高階函數 什么是高階函數? 接受…