Python

b站短视频爬取下载

Jaydon · 11月30日 · 2019年 290次已读

1.环境:python3.6.5 + windows10

2.依赖包: requests(需安装)、multiprocessing(多线程下载)、fake-useragent(需安装)

3.短视频网址(https://vc.bilibili.com/p/eden/rank#/?tab=全部

一、分析网站

1.打开短视频网址,可以看到如下页面

2.打开浏览器开发者模式,快捷键是F12

选择xhr选项,可以逐个网址去看一下,然后可以找到这些短视频的来源地址。(数据来源一般都是xhr或者直接就在网页源代码里面)

3.分析请求参数(这种都是有多个链接的,不断下拉滚动条,这个链接就重复出现了,其实就是分页)

可以看到每一页的请求参数,只有一个参数在变化,next_offset,我们使用循环去递增这个参数,就能把所有视频下载链接获取到。

二、编写代码

# codong:utf8

import requests
import traceback
from fake_useragent import UserAgent
from multiprocessing.dummy import Pool
import string
import random
import os

ua = UserAgent()


class BaseCrawler(object):

    def __init__(self, url):
        self.url = url
        self.headers = {"User-Agent": ua.random}

    def get_web_data(self, method, params="", data="", get_type=1):
        try:
            response = requests.request(url=self.url, headers=self.headers, method=method, params=params, data=data, timeout=5)
            print(response.status_code, response.url)
            response.encoding = response.apparent_encoding
            if get_type == 1:
                return response.text
            else:
                return response.json()
        except:
            traceback.print_exc()
            return

    @staticmethod
    def create_random_str(length=12):
        str_data = string.ascii_letters + string.digits
        return "".join(random.sample(str_data, length))

    def download_mp4(self, url):
        try:
            response = requests.get(url, headers=self.headers)
            data = response.content
            if not os.path.exists("mp4"):
                os.mkdir("mp4")
            filename = os.getcwd()+"/mp4/"+self.create_random_str()+".mp4"
            with open(filename, "wb") as f:
                f.write(data)
        except:
            print("download error!!!")

    def download(self, urls):
        if not isinstance(urls, list):
            urls = [urls]
        pool = Pool(4)
        pool.map(self.download_mp4, urls)
        pool.close()
        pool.join()

上面这是一个通用的爬虫类,里面有请求、下载以及生成随机字符串公共方法,以后写爬虫,只要继承这个公共类,就减少重复性的代码了。

# coding:utf8
"""
网站小视频地址https://vc.bilibili.com/p/eden/rank#/?tab=全部
"""
from base_crawler import BaseCrawler
import time


class CrawlerBilibili(BaseCrawler):

    def parse_web_data(self, params, video_url):
        webData = self.get_web_data("get", get_type=2, params=params)
        if not webData:
            return
        items = webData["data"]["items"]
        for item in items:
            video_url.append(item["item"]["video_playurl"])


if __name__ == '__main__':
    url = "http://api.vc.bilibili.com/board/v1/ranking/top"
    crawler = CrawlerBilibili(url)
    video_url = list()
    for i in range(1, 101, 10):
        if i == 1:
            next_offset = ""
        else:
            next_offset = i
        params = {
            "page_size": 10,
            "next_offset": next_offset,
            "tag": "今日热门",
            "platform": "pc"
        }
        crawler.parse_web_data(params, video_url)
        time.sleep(1)
    crawler.download(video_url)

最后运行代码就可以啦,下面展示下载的成果~

0 条回应