本文將深入講解兩大主流短視頻平臺(抖音、B站)的爬蟲實戰技術,提供可直接運行的代碼解決方案,并分享突破反爬機制的核心技巧。
一、平臺特性與爬蟲難點對比
平臺 | 數據價值 | 主要反爬措施 | 推薦抓取方式 |
---|---|---|---|
抖音 | 視頻數據、用戶畫像、熱榜 | 簽名驗證、TLS指紋、滑塊驗證 | Web接口+簽名破解 |
B站 | 彈幕、評論、視頻元數據 | Referer校驗、Cookie驗證、頻率限制 | API接口+模擬登錄 |
二、抖音爬蟲實戰:獲取用戶視頻數據
核心原理:破解X-Bogus簽名
抖音通過X-Bogus參數保護接口,需使用JavaScript逆向技術生成簽名。
python
import requests import execjs # 執行JS代碼 import json# 加載本地JS簽名生成腳本(需提前保存) with open('douyin_xbogus.js', 'r') as f:js_code = f.read() ctx = execjs.compile(js_code)def get_douyin_user_videos(user_id):headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36','Cookie': '你的抖音Cookie' # 通過瀏覽器獲取}# 構造原始URLbase_url = f"https://www.douyin.com/aweme/v1/web/aweme/post/?device_platform=webapp&user_id={user_id}"# 通過JS生成X-Bogus簽名xbogus = ctx.call('generateXbogus', base_url)signed_url = base_url + "&X-Bogus=" + xbogustry:response = requests.get(signed_url, headers=headers)data = response.json()# 解析視頻數據videos = []for aweme in data['aweme_list']:video_info = {'id': aweme['aweme_id'],'desc': aweme['desc'],'create_time': aweme['create_time'],'duration': aweme['duration'] // 1000, # 轉為秒'likes': aweme['statistics']['digg_count'],'comments': aweme['statistics']['comment_count'],'url': aweme['video']['play_addr']['url_list'][0]}videos.append(video_info)return videosexcept Exception as e:print(f"抓取失敗: {str(e)}")return []# 使用示例 if __name__ == "__main__":user_id = "123456789" # 替換為目標用戶IDvideo_data = get_douyin_user_videos(user_id)print(f"獲取到{len(video_data)}個視頻")for video in video_data[:3]:print(video['desc'])
關鍵技術點:
X-Bogus簽名生成:
需要逆向抖音官方JavaScript生成算法
使用PyExecJS執行JS代碼生成有效簽名
關鍵參數獲取:
user_id
:通過分享鏈接獲取(需URL解碼)Cookie
:登錄后從瀏覽器開發者工具獲取
數據解析技巧:
視頻真實地址在
play_addr.url_list
時間戳需要轉換格式
注:完整X-Bogus生成JS代碼需單獨獲取(因篇幅限制未展示)
三、B站爬蟲實戰:獲取視頻彈幕與評論
方案1:直接獲取彈幕數據(無需登錄)
python
import requests import re import xml.etree.ElementTree as ETdef get_bilibili_danmaku(cid):""" 通過視頻CID獲取彈幕 """url = f"https://api.bilibili.com/x/v1/dm/list.so?oid={cid}"response = requests.get(url)response.encoding = 'utf-8'# 解析XML彈幕數據danmaku = []root = ET.fromstring(response.text)for d in root.findall('d'):attrs = d.attrib['p'].split(',')danmaku.append({'time': float(attrs[0]),'type': int(attrs[1]),'size': int(attrs[2]),'color': f"#{int(attrs[3]):06X}",'timestamp': int(attrs[4]),'text': d.text})return danmaku# 使用示例 cid = "45678901" # 通過視頻API獲取 danmaku_data = get_bilibili_danmaku(cid) print(f"獲取到{len(danmaku_data)}條彈幕")
方案2:獲取視頻評論(需模擬登錄)
python
import requests import time import randomdef get_bilibili_comments(bvid):headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36','Referer': f'https://www.bilibili.com/video/{bvid}','Cookie': '你的B站Cookie'}comments = []page = 1while True:url = f"https://api.bilibili.com/x/v2/reply?jsonp=jsonp&pn={page}&type=1&oid={get_aid(bvid)}&sort=2"try:response = requests.get(url, headers=headers)data = response.json()if data['code'] != 0:print(f"錯誤: {data['message']}")break# 解析評論數據for reply in data['data']['replies']:comments.append({'user': reply['member']['uname'],'content': reply['content']['message'],'like': reply['like'],'time': time.strftime("%Y-%m-%d %H:%M", time.localtime(reply['ctime']))})print(f"已獲取第{page}頁評論")page += 1# 隨機延遲防止封禁time.sleep(random.uniform(1.5, 3))# 檢查是否還有下一頁if page > data['data']['page']['count'] // 20:breakexcept Exception as e:print(f"抓取出錯: {str(e)}")breakreturn commentsdef get_aid(bvid):""" 將BV號轉換為AV號 """table = 'fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF'tr = {table[i]: i for i in range(58)}s = [11, 10, 3, 8, 4, 6]xor = 177451812add = 8728348608r = 0for i in range(6):r += tr[bvid[s[i]]] * 58 ** ireturn (r - add) ^ xor# 使用示例 if __name__ == "__main__":bvid = "BV1gK4y1N7Jb" # 替換為目標視頻BV號comment_data = get_bilibili_comments(bvid)print(f"獲取到{len(comment_data)}條評論")
關鍵技術點:
CID/AID獲取:
彈幕需要CID參數(通過視頻API獲取)
評論需要AID(BV號需轉換為AV號)
反爬突破技巧:
必須攜帶Referer請求頭
Cookie需定期更新(有效期約1天)
請求間隔需隨機化(1-3秒)
數據解析:
彈幕為XML格式,屬性包含位置/顏色/時間
評論API返回分頁JSON數據
四、高級反爬對抗方案
反爬類型 | 解決方案 | 工具推薦 |
---|---|---|
簽名驗證 | JavaScript逆向 | PyExecJS/Frida |
TLS指紋 | 修改客戶端指紋 | curl_cffi/requests_toolbelt |
滑塊驗證 | 打碼平臺/OCR識別 | ddddocr/第三方打碼API |
IP限制 | 代理IP輪換 | 快代理/站大爺 |
代理IP示例代碼:
python
from itertools import cycleproxies = cycle(['http://user:pass@192.168.1.1:8080','http://user:pass@192.168.1.2:8080' ])def make_request(url):proxy = next(proxies)try:return requests.get(url, proxies={"http": proxy}, timeout=10)except:return make_request(url) # 自動切換下一個代理
五、法律合規邊界
允許操作:
抓取公開視頻信息(非隱私內容)
個人學習研究目的
遵守robots.txt限制
禁止行為:
破解付費內容
抓取用戶私信/手機號等隱私
商業用途未經授權
高頻請求影響服務(>1次/秒)
建議:商業項目使用官方API(抖音開放平臺/B站開放接口),個人學習控制請求頻率
六、最佳實踐建議
數據存儲優化:
使用消息隊列(RabbitMQ)緩沖請求
分布式存儲(MongoDB分片集群)
錯誤處理機制:
python
# 重試裝飾器示例 from tenacity import retry, stop_after_attempt, wait_random@retry(stop=stop_after_attempt(3), wait=wait_random(min=2, max=5)) def safe_request(url):response = requests.get(url)response.raise_for_status()return response
監控體系:
成功率監控(Prometheus)
代理IP可用性檢測
自動切換簽名算法版本
通過本指南,你可快速構建抖音/B站數據采集系統。隨著平臺反爬策略升級,需要持續關注接口變化并更新破解方案。建議優先考慮官方API方案,復雜場景可結合Selenium模擬真人操作。