Python中如何爬取Blob URL的内容?

向 b 站这种 https://www.bilibili.com/video/av17939763/?spm_id_from=333.334.chief_recommend.17 video 标签全部是 blob url,看了下接口都是需要签名的,只有看懂混淆的 js 然后找签名算法来爬视频这一种办法吗???


Python中如何爬取Blob URL的内容?

3 回复

要爬取Blob URL的内容,关键在于理解Blob URL是浏览器为本地二进制数据生成的临时引用,无法直接通过requests库获取。你需要用Selenium这类浏览器自动化工具来模拟真实访问。

核心思路是:用Selenium打开页面,让页面正常加载并执行JavaScript生成Blob,然后通过执行JavaScript代码来获取Blob的实际数据。

下面是一个完整示例,演示如何爬取包含Blob音频的页面:

from selenium import webdriver
from selenium.webdriver.common.by import By
import time
import requests
import base64

def download_blob_content(url, output_file="blob_content.mp3"):
    """
    下载Blob URL指向的内容
    
    参数:
        url: 包含Blob资源的网页URL
        output_file: 保存的文件名
    """
    # 设置Chrome选项
    options = webdriver.ChromeOptions()
    options.add_argument('--headless')  # 无头模式,不显示浏览器窗口
    
    driver = webdriver.Chrome(options=options)
    
    try:
        # 打开目标网页
        driver.get(url)
        time.sleep(3)  # 等待页面加载和JavaScript执行
        
        # 查找页面中的音频元素(根据实际情况调整选择器)
        audio_element = driver.find_element(By.TAG_NAME, "audio")
        
        # 获取音频的src属性,可能是Blob URL
        audio_src = audio_element.get_attribute("src")
        
        if audio_src and audio_src.startswith('blob:'):
            print(f"找到Blob URL: {audio_src}")
            
            # 执行JavaScript获取Blob数据
            # 这段JS代码创建一个XMLHttpRequest来获取Blob数据
            js_script = """
            var callback = arguments[arguments.length - 1];
            var xhr = new XMLHttpRequest();
            xhr.open('GET', '%s', true);
            xhr.responseType = 'blob';
            xhr.onload = function() {
                var reader = new FileReader();
                reader.onloadend = function() {
                    callback(reader.result);
                };
                reader.readAsDataURL(xhr.response);
            };
            xhr.send();
            """ % audio_src.replace('blob:', '')
            
            # 执行JavaScript并获取结果
            blob_data_url = driver.execute_async_script(js_script)
            
            # 解析Data URL(格式为:data:audio/mpeg;base64,xxxxxxxx)
            if blob_data_url.startswith('data:'):
                # 提取Base64编码的数据
                header, data = blob_data_url.split(',', 1)
                # 解码Base64数据
                audio_data = base64.b64decode(data)
                
                # 保存到文件
                with open(output_file, 'wb') as f:
                    f.write(audio_data)
                
                print(f"文件已保存: {output_file}")
                return True
                
    except Exception as e:
        print(f"发生错误: {e}")
        return False
        
    finally:
        driver.quit()

# 使用示例
if __name__ == "__main__":
    # 替换为实际的网页URL
    target_url = "https://example.com/page-with-blob-audio"
    download_blob_content(target_url, "downloaded_audio.mp3")

关键点说明:

  1. 为什么用Selenium:Blob URL只在浏览器会话中有效,需要真实的浏览器环境来生成和访问。

  2. JavaScript注入:通过execute_async_script执行自定义JS代码,使用XMLHttpRequest获取Blob数据,然后用FileReader转换为Data URL。

  3. Base64解码:Data URL包含Base64编码的二进制数据,需要解码后保存。

  4. 元素定位:示例中通过find_element(By.TAG_NAME, "audio")查找音频元素,实际使用时可能需要根据页面结构调整选择器。

注意事项:

  • 确保已安装ChromeDriver并配置好路径
  • 根据页面加载时间调整time.sleep的等待时间
  • 如果页面有反爬机制,可能需要添加更多Selenium选项

替代方案: 如果页面是通过JavaScript动态加载Blob的,你可能需要监听网络请求来直接获取原始数据URL。可以通过Selenium的Performance Log或使用mitmproxy等工具来拦截网络请求。

总结来说,爬Blob就得用浏览器自动化工具来模拟真实访问环境。


最好先去了解一下什么是 Blob。这是 JS 代码返回的数据的。像 B 站是因为使用了 flv.js ,作用是把 flv 重新封装成 mp4 格式,让浏览器播放。

接口确实需要签名…如果想要自动化的话就扒算法吧……半自动就是 f12 查看签名。我有段代码就是先 f12 看签名后,使用 fetch 下载视频,然后在网页上生成 blob 链接的方式来下载的。而且视频是分段的,还需要用软件来合并

回到顶部