IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> 爬取网站未加密ts视频文件 -> 正文阅读

[Python知识库]爬取网站未加密ts视频文件

爬取主页面中的视频页面地址

  • 正则表达式测试:推荐这个网址进行测试,测试网址,不建议整个页面进行正则匹配,我感觉不如搭配着好用
  • 使用requests模块的时候不要使用代理软件,例如clash,否则会引发一串报错
import time
import requests
from bs4 import BeautifulSoup
import re
import os

# UA伪装
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36'
}

# 匹配标题和网址
regex = r"<a href=\"(.*?)\">[\D\d]*?loadBannerDirect\('(.*?)',[\D\d]*?\"headline\">(.*?)</h2>[\D\d]*"

# 获取页面数据

def get_num_url(page_num):
    # 进行页码循环
    for num in range(1, page_num):
        # 与页码拼接成链接
        urls = '**************/page/{}/'.format(num)
        # print(urls)
        # 获取页面数据
        html_data = requests.get(url=urls, headers=headers).text
        # 对界面用bs4解析
        soup = BeautifulSoup(html_data, 'lxml')
        # 获取article标签下的子a标签
        str_lists = soup.select('article > a')
        # 对a标签遍历
        for str_list in str_lists:
            # 对a标签使用正则解析
            matches = re.findall(regex, str(str_list), re.S)
            # 解析数据就是((网址,图片,名字))
            with open('./page{}.txt'.format(str(num)), 'a', encoding='utf-8') as ft:
                try:
                    # 名字过长的是无效数据
                    if len(matches[0][2]) < 150:
                        ft.write(str(matches[0]) + '\n')
                except IndexError:
                    pass
                    # print(str(matches[0]))
        # 休眠
        time.sleep(0.5)


if __name__ == '__main__':
    get_num_url(10)

  • 大体就是从主页面爬取其中视频页的预览图,视频页的地址,视频页的名字
  • 其中正则表达式还有bs4解析都需要根据你自己想爬取的网页进行重新编排,该代码只能看个流程

从视频页面里爬取m3u8地址,并下载其中的ts文件

import time
from datetime import datetime
import requests
from lxml import etree
import os
import re

# 重新从上一步保存的文本里提取三个部分,网址,图片网址,名字
regex_txt = r"\('(.*?)', '(.*?)', '(.*?)'\)"
# 匹配出链接
regex_url = r".*?\"url\":\"(.*?)\",\"pic\".*"
# UA伪装
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36'
}

# 从视频地址下载m3u8文件,并返回基地址
def download_m3u8(urls, name):
    # 获取页面数据
    html_data = requests.get(url=urls, headers=headers).text
    # 因为该网页不标准,设定解析格式
    parser = etree.HTMLParser(encoding='utf-8')
    # 初始化etree
    tree = etree.HTML(html_data, parser=parser)
    # 获取链接所在处内容,需要根据自己的页面进行解析
    video_content = tree.xpath('//div[@class="dplayer"]/@data-config')
    # 进行正则匹配取出链接地址
    video_url = re.match(regex_url, video_content[0], re.S).group(1)
    # 根据获得的链接格式修改成标准格式
    video_url = video_url.replace('\\', '')
    # 将名字中的空格剔除,防止创建文件夹失败
    name = name.replace(' ', '')
    folder_path = './{}'.format(name)
    # 不存在文件夹则创建
    if not os.path.exists(folder_path):
        os.mkdir(folder_path)
    m3u8_path = folder_path + '/index.m3u8'
    with open(m3u8_path, 'w', encoding='utf-8') as fm:
        fm.write(requests.get(url=video_url, headers=headers).text)

    time.sleep(1)
    # 返回所在文件夹地址,m3u8地址,video部分基地址
    return folder_path, m3u8_path, video_url[:-10]


# 从m3u8文件中取出并生成ts文件的下载链接
def get_ts_urls(m3u8_path, base_url):
    urls = []
    with open(m3u8_path, "r") as file:
        lines = file.readlines()
        for line in lines:
            if line.endswith(".ts\n"):
                urls.append(base_url + line.strip("\n"))
    return urls

# 下载ts文件
def download_ts(ts_urls, download_path):
    # 对ts文件的url进行遍历
    for ts_url in ts_urls:
        # 第几个ts文件,获取名字
        file_name = ts_url.split("/")[-1]
        # 与存储地址合并成一个完整文件路径
        ts_path = download_path + "/{}".format(file_name)
        print(ts_path)
        print(ts_url)
        # 如果不存在这个ts文件,则进行下载,否则略过避免重复对方服务器压力过大
        if not os.path.exists(ts_path):
            # 打开你创建的ts文件
            with open(ts_path, "wb") as fb:
                try:
                    # 获取ts链接二进制内容,写入文件
                    response = requests.get(headers=headers, url=ts_url).content
                    fb.write(response)
                # 由于网络问题会导致这两个错误,我没有进行处理直接下一个
                except TimeoutError:
                    pass
                except ConnectionError:
                    pass
                # except MaxRetryError:
                #     pass
        else:
            print("{} 已经存在,开始下载下一个ts".format(file_name))
            continue
        # 休眠
        # time.sleep(0.5)


def get_page_video(page_num):
    # 这是上一步爬取的txt,包括链接 图片 名字
    with open('page{}.txt'.format(page_num), 'r', encoding='utf-8') as ft:
        # 读取文件全部内容
        lines_data = ft.readlines()
        for line_data in lines_data:
            # match.group(3)是名字,(1)是网址
            match = re.match(regex_txt, line_data, re.S)
            url = match.group(1)
            name = match.group(3)
            print(name)
            folder_path, m3u8_path, base_url = download_m3u8(url, name)
            print(folder_path)
            ts_urls = get_ts_urls(m3u8_path, base_url)
            download_ts(ts_urls, folder_path)


# 按间距中的绿色按钮以运行脚本。
if __name__ == '__main__':
    for i in range(1, 9):
        get_page_video(i)

  • 这部分大体是根据上一步爬取的视频页地址,对视频页解析获取m3u8文件,然后对m3u8文件进行读取,然后拼接m3u8文件里所有的ts文件地址后进行下载,存储到文件夹里
  • 同理这些也只能看看流程和处理方式,其中正则和xpath解析也需要根据你的爬取界面的链接进行匹配

bs4与Xpath解析流程与方法

'''
bs4解析流程:
1. 对象实例化 将html文档加载当前对象中
    b = open('n.html','r',encoding = 'utf-8')
    soup = BeautifulSoup(b,'lxml')
    
    b = respons.text
    soup = BeautifulSoup(b,'lxml')
2. 
#返回第一次出现的a标签
    soup.a 等同于 soup.find('a')
#返回第一个a标签里含有class为song的标签
    soup.find('a',class_='song')
#返回所有a标签
    soup.findall('a')
#选择器,例如id class 标签等等
    soup.select('')
    #类选择器(class标签):.(类的值)
    #ID选择器(ID标签):#(ID的值)
    #标签选择器:标签名
    例如:soup.select('.rang > #lisd > li > a')
    选择所有 类名为rang下,ID为lisd下,li标签下的a标签,其中>代表一个层级(子代选择器),必须是紧挨着自己的下一层
    soup.select('.rang > #lisd a')
    选择所有 类名为rang下,ID为lisd下所有a标签,其中空格表示后代选择器,中间可以隔很多代
# 获取标签间的文本数据
    soup.a.text/string,text获取标签下所有内容,string只获取直系文本
# 获取标签中的属性值
    soup.a['href']
'''
'''
xpath解析:
    实例化etree对象,将被解析的页面源码数据加载到对象中
    调用etree对象的xpath方法结合着xpath表达式实现标签的定位和内容捕获
流程:
    1.将本地html文档中源码加载到对象中
        etree.parse(filepath)
    2.将互联网获取的数据加载到对象中
        etree.HTML(page_text)
    3.xpath表达式
    /:表示的是从根节点开始定位。表示的是一个层级。
    //∶表示的是多个层级。也可以表示从任意位置开始定位。
    属性定位: //div[@class='song']  标准形式tag[@attrName="attrValue"]
    索引定位: //div[@class='song']/p[3]  索引是从1开始的。
    取文本:
        /text()获取的是标签中直系的文本内容
        //text(标签中非直系的文本内容(所有的文本内容)
    取属性:
        /@attrName   ==> 例如:img/@src 就是取img的src的属性值

'''
  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2022-03-30 18:19:14  更:2022-03-30 18:22:38 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 20:00:28-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码