Python爬取 分析Ajax爬取B站python视频---详细资料

本文介绍了一种使用Python爬取B站Python相关视频的方法,包括如何定位API接口、构造URL参数实现多页爬取,并提供了具体代码实现,涵盖视频标题、作者、播放量等信息的抓取。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Flag:一天一爬虫。

这篇是转的:https://blog.youkuaiyun.com/sixkery/article/details/81946308

亲测有效,

对转载网站的分析做进一步分析补充:

分析页面:

如何获取api?

这次我直接打开开发者工具,切换到Network下查找api,要点击Python旁边的搜索按钮,不然Network一片空白,

 点击搜索之后:

 会在其中找到,一个以api开头的网址,但是我们不能用此url作为我们爬取的对象,因为此url,没有包含page={},无法多页爬取,

此url只搜集这一页的视频信息。

此url

https://api.bilibili.com/x/web-interface/search/all?jsonp=jsonp&highlight=1&keyword=python&callback=__jp0

 然后,

 依次点击尝试,

找到page,意味着可以多页爬取了,然后就是构造url。

代码:

import requests
import json, re, time
from requests.exceptions import RequestException


class Spider():

    def get_page(self, page):
        try:
            headers = {
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64)'
                              ' AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36',
            }
            url = 'https://api.bilibili.com/x/web-interface/search/type?jsonp=jsonp&&search_type=video&highlight=1&keyword=python&page={}'.format(
                page)
            r = requests.get(url, headers)
            if r.status_code == 200:
                return r.text
            else:
                print(r.status_code)
        except RequestException:
            print('请求失败')
            return None

    def parse_page(self, html):
        # 转换成JSON对象,好操作
        data = json.loads(html)

        results = data.get('data').get('result')
        for result in results:
            # 获取图片地址
            image_url = result['pic']
            # 获取视频地址
            video_url = result['arcurl']
            # 获取作者
            video_author = result['author']
            # 获取视频标题,中间有额外的字符,用re替换一下
            video_title = result['title']
            video_title = re.sub('<em class="keyword">[Pp]ython</em>', 'Python', video_title)
            # 获取播放量
            video_play = result['play']
            # 获取上传时间,这里将时间戳转换成标准格式
            video_date = result['pubdate']
            timestr = time.localtime(video_date)
            video_date = time.strftime('%Y-%m-%d %H-%M-%S', timestr)
            print(image_url, video_url, video_title, video_play, video_date)

    def run(self):#爬取前三页
        for i in range(1, 3):
            html = self.get_page(i)
            self.parse_page(html)


def main():
    spider = Spider()
    spider.run()


if __name__ == '__main__':
    main()

爬取结果,

本来想爬一下那个all的api,奈何能力不够,找代理池,换header都解决不了问题,,

此处先贴上代码,以后解决。

import requests
import json, re, time
from requests.exceptions import RequestException
import random
import urllib as ulb
class Spider():

    def get_page(self):
        try:
            my_headers = [
                "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36",
                "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36",
                "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:30.0) Gecko/20100101 Firefox/30.0",
                "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.75.14 (KHTML, like Gecko) Version/7.0.3 Safari/537.75.14",
                "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Win64; x64; Trident/6.0)",
                'Mozilla/5.0 (Windows; U; Windows NT 5.1; it; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11',
                'Opera/9.25 (Windows NT 5.1; U; en)',
                'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)',
                'Mozilla/5.0 (compatible; Konqueror/3.5; Linux) KHTML/3.5.5 (like Gecko) (Kubuntu)',
                'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.12) Gecko/20070731 Ubuntu/dapper-security Firefox/1.5.0.12',
                'Lynx/2.8.5rel.1 libwww-FM/2.14 SSL-MM/1.4.1 GNUTLS/1.2.9',
                "Mozilla/5.0 (X11; Linux i686) AppleWebKit/535.7 (KHTML, like Gecko) Ubuntu/11.04 Chromium/16.0.912.77 Chrome/16.0.912.77 Safari/535.7",
                "Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:10.0) Gecko/20100101 Firefox/10.0 "
            ]
            headers =random.choice(my_headers)
            url = 'https://api.bilibili.com/x/web-interface/search/all?jsonp=jsonp&highlight=1&keyword=python&callback=__jp0'
            proxies = {
                'https': 'https://114.99.7.122:8752'}
            proxy_list = [
                '183.95.80.102:8080',
                '123.160.31.71:8080',
                '115.231.128.79:8080',
                '166.111.77.32:80',
                '43.240.138.31:8080',
                '218.201.98.196:3128'
            ]
            # 随机从IP列表中选择一个IP
            proxy = random.choice(proxy_list)
            # 基于选择的IP构建连接
            urlhandle = ulb.request.ProxyHandler({'http': proxy})
            opener = ulb.request.build_opener(urlhandle)
            ulb.request.install_opener(opener)

            r = requests.get(url, headers,proxies=proxies)
            if r.status_code == 200:
                return r.text
            else:
                print(r.status_code)
        except RequestException:
            print('请求失败')
            return None

    def parse_page(self, html):
        print(html)
        # 转换成JSON对象,好操作
        # data = json.loads(html)
        # print(data)
#        results = data.get('data').get('result')
#         results=data.get('data').get('result').get('video')
#         for result in results:
#             author_=result['author']
#             print(author_)
            # # 获取图片地址
            # image_url = result['pic']
            # # 获取视频地址
            # video_url = result['arcurl']
            # # 获取作者
            # video_author = result['author']
            # # 获取视频标题,中间有额外的字符,用re替换一下
            # video_title = result['title']
            # video_title = re.sub('<em class="keyword">[Pp]ython</em>', 'Python', video_title)
            # # 获取播放量
            # video_play = result['play']
            # # 获取上传时间,这里将时间戳转换成标准格式
            # video_date = result['pubdate']
            # timestr = time.localtime(video_date)
            # video_date = time.strftime('%Y-%m-%d %H-%M-%S', timestr)
            # print(image_url, video_url, video_title, video_play, video_date)

    def run(self):#爬取前三页
        html = self.get_page()
        self.parse_page(html)
        # for i in range(1, 3):
        #     html = self.get_page(i)
        #     self.parse_page(html)


def main():
    spider = Spider()
    spider.run()


if __name__ == '__main__':
    main()

### 使用 Python 实现 B 视频详情数据抓取 为了实现这一目标,可以采用 `requests` 和 `BeautifulSoup` 库来处理静态页面中的 HTML 数据;对于动态加载的内容,则可能需要用到像 Selenium 这样的工具模拟浏览器行为获取 JavaScript 渲染后的 DOM 结构[^1]。 #### 准备工作 安装必要的库: ```bash pip install requests beautifulsoup4 selenium pandas ``` #### 获取视频详情页 URL 及其 ID 通常情况下,每条视频都有唯一的 AV/BV 编号作为标识符。可以通过正则表达式从给定链接中提取这些编号用于后续 API 请求构建[^2]。 #### 发送 HTTP GET 请求并解析响应体 利用 `requests.get()` 方法向服务器发起请求,并通过 BeautifulSoup 解析返回的文档对象模型 (DOM),定位到 `<script>` 标签内的 JSON 字符串部分,其中包含了视频的具体信息如标题、封面图地址等。 #### 处理 AJAX 加载的数据 如果遇到异步加载的情况,比如评论区或者弹幕列表,就需要进一步研究官方提供的 RESTful 接口文档,直接调用相应的端点以获得更完整的资源描述[^3]。 下面是一个简单的例子展示如何读取和打印某个特定 BV 号对应的视频基本信息: ```python import re import json from bs4 import BeautifulSoup as BS import requests def get_video_info(bvid): url = f"https://www.bilibili.com/video/{bvid}" headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)', 'Referer': url, } response = requests.get(url=url, headers=headers) soup = BS(response.text, "html.parser") script_tags = str(soup.find_all('script')) pattern = r'window.__INITIAL_STATE__=(.*?);\(function\(\)' match_result = re.findall(pattern, script_tags) if not match_result: raise ValueError("Failed to find video info.") data_str = match_result[0].strip() try: parsed_json = json.loads(data_str)['videoData'] title = parsed_json['title'].replace("\n", "") desc = parsed_json['desc'] print(f"Title: {title}") print(f"Description:\n{desc}") except KeyError as e: print(e) if __name__ == "__main__": bvid_example = input("Enter the target video's BV number:") get_video_info(bvid=bvid_example) ``` 此脚本会访问指定的 B 视频页面并通过查找包含初始状态的对象字面量来抽取所需的元数据字段。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值