2022年4月26日更新

更新了Windows版本的代码和exe可执行文件。

更新内容:

  • 使用了多进程下载,极大提升了下载速度;
  • 换成了91porny域名,需要翻墙;
  • 更新了文件存储名称,使用视频标题存储;
  • 更新了存储位置,exe版可以选择,Python版存储在程序所在的文件夹。

mac版没有更新,可以照着Python代码改。


其实我自己是不怎么看这网站的内容的,但我的舍友很喜欢看,经常问我借VPN。

写这个小程序的动机是,我偶然发现了一个91视频的仿站,或者说采集站,我感觉比原版做的更加清晰精致,方便提取视频目录和地址,但仍然没有提供下载功能;网络上一些已有的视频提取网站不能直接合并下载,也不能免翻墙下载。

这里提供了mac版和windows版的Python小程序,windows版本的小程序还提供了exe版本,可以直接执行。

源码中提供了两个url,选择其一即可。91porny需要翻墙。

视频的viewkey就是你想下载的视频url中,91porn.com/view_video.php?viewkey= 后面的部分,或者 91porny.com/video/view/ 最后的部分

exe格式可执行文件

windows版

import requests, re, os, socket
from bs4 import BeautifulSoup
from urllib.request import urlretrieve
from tqdm import tqdm
import multiprocessing as mp

def get_title(key):
    detail_url = 'https://91porny.com/video/view/{}'.format(key)
    r = requests.get(detail_url)
    soup = BeautifulSoup(r.text, 'lxml')
    title = soup.h4.text
    print('将下载这个视频:{}'.format(title))
    return re.sub('\s','',title)

def make_dir():
    os.chdir(os.path.dirname(__file__))
    if os.path.exists('videos_91'):
        os.system('rd /s /q videos_91')
    os.mkdir('videos_91')
    os.chdir('videos_91')

def get_ts_list(key):
    url = 'https://91porny.com/video/embed/{}'.format(key)
    r = requests.get(url)
    soup = BeautifulSoup(r.text, 'lxml')
    m3u8_url = soup.find('video').get('data-src')
    m3u8 = '/'.join(m3u8_url.split('/')[:-1])
    index = requests.get(m3u8_url).text
    ts_list = re.findall('index.*?ts', index)
    return [(m3u8, i) for i in ts_list]

def downloader(ts):
    ts_url = '{}/{}'.format(ts[0], ts[1])
    urlretrieve(ts_url, ts[1])

def rename_ts(path, ts_list):
    rename_dict = {i[1]:'{}.ts'.format(ts_list.index(i)+1).zfill(8) for i in ts_list}
    for r, ds, fs in os.walk(path):
        for f in fs:
            os.rename(f,rename_dict[f])

def merge_ts(path, title):
    os.chdir('..')
    cwd = os.getcwd()
    cmd = 'copy /b videos_91\*.ts {}.mp4'.format(title)
    os.system(cmd)
    os.system('rd /s /q videos_91')
    input('视频已经存储为 {}\{}.mp4\n请按任意键退出。'.format(cwd, title))

if __name__ == '__main__':

    socket.setdefaulttimeout(20)

    key = input('请输入视频的viewkey:')
    title = get_title(key)
    make_dir()
    ts_list = get_ts_list(key)

    p = mp.Pool()
    for _ in tqdm(p.imap(downloader,ts_list), total=len(ts_list)): pass
    p.close()
    p.join()

    path = os.getcwd()
    rename_ts(path, ts_list)
    merge_ts(path, title)

mac版