1.python爬虫爬取视频网站的视频可下载的源url

news2024/11/26 21:32:56

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 一、爬取的源网站
  • 二、爬取过程详解
    • 1.首先我们需要解析网站的源码,按F12,在Elements下查看网站的源码
    • 2.获取视频的页数
    • 3.获取每一页所哟视频的详情页面的url,注意这不是最终的下载视频的url
    • 4.获取视频的下载url
      • 解决方法
  • 三、完整的实现代码
  • 总结


一、爬取的源网站

http://www.lzizy9.com/
在这里以电影片栏下的动作片为例来爬取。
在这里插入图片描述
在这里插入图片描述
可以看到视频有多页,因此需要多页爬取。

二、爬取过程详解

1.首先我们需要解析网站的源码,按F12,在Elements下查看网站的源码

在这里插入图片描述

2.获取视频的页数

往往,视频一个网站的url是有规律可循的,这样可以方便我们的爬取操作,比如视频的第一页的url为http://www.lzizy9.com/index.php/vod/type/id/6.html
在这里插入图片描述

然后我们查看视频的第二页的url,
http://www.lzizy9.com/index.php/vod/type/id/6/page/2.html
在这里插入图片描述
后面的第三页url为http://www.lzizy9.com/index.php/vod/type/id/6/page/3.html,从中我们可以找到规律为第几页最后就是几。
但是看似第一个好像没有序号,我们在点第一页回来看看,会发现第一页也有了序号,其实这是因为第一页默认的没有显示罢了,其实第一页的url也就是http://www.lzizy9.com/index.php/vod/type/id/6/page/1.html,这样我们就可以找到页的url的规律了。
然后解析网站的源码来获取页数,可以看到图中标红框的部分就是我们要获取的视频的最后一页的信息,其中/index.php/vod/type/id/6/page/61.html中的61就是要页数了。
在这里插入图片描述
获得页数的代码如下:

	# 通过requests.get方法可以发送GET请求
	html_doc = requests.get(f"http://www.lzizy9.com/index.php/vod/type/id/6/page/1.html", headers=headers)

    # BeautifulSoup将复杂的HTML文件转化为一个Python对象,使得用户可以更方便地解析、搜索和修改HTML内容。
    # html_doc.text获取网页的HTML内容
    soup = BeautifulSoup(html_doc.text, 'html.parser')

    # 使用findALL提取网页中的信息,其返回的是一个可迭代的对象,具体的用法自行搜索
    # 我们要爬取所有的视频,需要识别视频一共有多少页,其返回结果为['/index.php/vod/type/id/6/page/61.html'],根据参数我们得知一共有61页视频
    href_values = [link['href'] for link in soup.findAll('a', title='尾页')]
    # 获取页数,并将字符串string转化为int整数
    end_page = int(href_values[0][30:32])

3.获取每一页所哟视频的详情页面的url,注意这不是最终的下载视频的url

以第一个视频为例,可以看到视频跳转到的界面的url的信息为/index.php/vod/detail/id/79854.html,实则网站的链接为http://www.lzizy9.com/index.php/vod/detail/id/73135.html,其省略了http://www.lzizy9.com而已。
在这里插入图片描述

我们对其进行定位,可以看到其在a标签下,class属性为module-item-title,这样我们就可以定位下来视频的详情界面的url了

		html_page = requests.get(f"http://www.lzizy9.com/index.php/vod/type/id/6/page/{page}.html", headers=headers)
        page_values = BeautifulSoup(html_page.text, "html.parser")

        # 找视频播放的链接,其在标签为a,class为"module-item-title"的下面
        href_players = [link['href'] for link in page_values.findAll('a', attrs={"class": "module-item-title"})]

4.获取视频的下载url

在视频的详情页,点击播放,然后按F12,从源码中寻找视频的下载的url,然后我们可以定位到这里
在这里插入图片描述
确认是否是可以下载的url的办法就是,我们把这个链接打开,发现其完全是一个播放的视频就是可以下载的url,如下。
网页里面除了一个视频其他的什么都没有。

在这里插入图片描述
然后我们定位这个链接的位置,发现其在iframe下面,然后继续使用findAll来寻找这个标签,发现现在返回的是空的。
这是因为这一部分的内容在JavaScript的代码中,为了能让我们看到其中的内容,浏览器会对JavaScript代码进行渲染,得到其中的内容后再呈现到我们面前。然而,爬虫程序无法对HTML文件中的JavaScript代码进行渲染。因此,如果我们的目标镶嵌在JavaScript中,那么我们爬到的数据往往就会缺少目标内容。
因此用下面的方法是无效的了

	 html_player = requests.get(url, headers=headers)
     player_values = BeautifulSoup(html_player.text, "html.parser")
     href_video = player_values.findAll('iframe')    # 注意这里是没有获取到信息的,因为HTML源码中的iframe标签是js加载的,因此通过requests无法获取,这里大家可以想别的办法获取视频的真实链接

解决方法

requests-html是一个轻量级的HTML解析模块,可以让我们模仿浏览器的行为,隐式地渲染js内容(即打开浏览器,渲染,点击等动作不会在前台展示过程,类似于selenium,只不过更轻量级)
安装模块:

pip install requests-html

代码如下,具体的findALL的寻找方法就不再赘述了,大家可以自行搜索怎么使用findALL来定位要获取的内容。

	session = HTMLSession()
	first_page = session.get(url)
	first_page.html.render(sleep=0.5)  # 留出网页渲染的时间
	soup = BeautifulSoup(first_page.html.html, features="lxml")  # 这里要用lxml

	# 注意要关闭session,要不然会不断的打开session,使得资源得不到释放,导致内存爆掉
    session.close()
	video_url = soup.findAll('td', attrs={'id': 'playleft'})
	video_name = soup.findAll('h1', attrs={'class': 'page-title'})
	video_url = video_url[0].contents[0]['src']
    video_name = video_name[0].contents[0].text

在这里这段代码first_page.html.render(sleep=0.5)可能会报错下载失败,解决方案可以看我的另一篇博客。

三、完整的实现代码

import requests
from bs4 import BeautifulSoup
import os
from requests_html import HTMLSession
import requests_html
import time
if __name__=='__main__':
    # 爬取的视频的信息的保存地址
    path = "D:\project\爬虫\爬取的视频"

    # headers是解决requests请求反爬的方法之一,相当于我们进去这个网页的服务器本身,假装自己本身在爬取数据。
    # 对反爬虫网页,设置headers的信息可以让我们的爬取操作模拟成浏览器取访问网站。
    # 当访问太频繁的时候,容易被服务器禁止访问,这时可以设置多个代理头,通过随机选择某一个代理头来爬取数据,这样可以避免使用同一个头频繁访问的封禁问题。
    headers = {
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36'
    }

    # 通过requests.get方法可以发送GET请求
    html_doc = requests.get(f"http://www.lzizy9.com/index.php/vod/type/id/6/page/1.html", headers=headers)

    # BeautifulSoup将复杂的HTML文件转化为一个Python对象,使得用户可以更方便地解析、搜索和修改HTML内容。
    # html_doc.text获取网页的HTML内容
    soup = BeautifulSoup(html_doc.text, 'html.parser')

    # 使用findALL提取网页中的信息,其返回的是一个可迭代的对象,具体的用法自行搜索
    # 我们要爬取所有的视频,需要识别视频一共有多少页,其返回结果为['/index.php/vod/type/id/6/page/61.html'],根据参数我们得知一共有61页视频
    href_values = [link['href'] for link in soup.findAll('a', title='尾页')]
    # 获取页数,并将字符串string转化为int整数
    end_page = int(href_values[0][30:32])
    # 遍历每一页来获取视频的url链接
    for page in range(1, end_page+1):
        # 此处获取网页信息与上面类似
        html_page = requests.get(f"http://www.lzizy9.com/index.php/vod/type/id/6/page/{page}.html", headers=headers)
        page_values = BeautifulSoup(html_page.text, "html.parser")

        # 找视频播放的链接,其在标签为a,class为"module-item-title"的下面
        href_players = [link['href'] for link in page_values.findAll('a', attrs={"class": "module-item-title"})]
        for href in href_players:
            try:
                # 寻找播放界面的规律,发现其除了id号不同以外,其他的都一样,从上面获取的视频播放链接中提取id号
                id = href[25:30]
                url = f"http://www.lzizy9.com/index.php/vod/play/id/{id}/sid/1/nid/1.html"

                # html_player = requests.get(url, headers=headers)
                # player_values = BeautifulSoup(html_player.text, "html.parser")
                # href_video = player_values.findAll('iframe')    # 注意这里是没有获取到信息的,因为HTML源码中的iframe标签是js加载的,因此通过requests无法获取,这里大家可以想别的办法获取视频的真实链接
                # print(href_video)

                # 由于使用requests无法获得js加载的内容,使用下面的方法可以解决这个问题
                session = HTMLSession()
                first_page = session.get(url)
                first_page.html.render(sleep=0.5)  # 留出网页渲染的时间
                soup = BeautifulSoup(first_page.html.html, features="lxml")  # 这里要用lxml
                video_url = soup.findAll('td', attrs={'id': 'playleft'})
                video_name = soup.findAll('h1', attrs={'class': 'page-title'})

                print(video_url[0].contents[0]['src'])
                print(video_name[0].contents[0].text)
                video_url = video_url[0].contents[0]['src']
                video_name = video_name[0].contents[0].text
                with open(os.path.join(path, video_name), 'w', encoding='utf-8') as file:
                    # 将url写入text文件
                    file.write(video_url)
            except:
                print('没有片源')

在这里加了一个try异常处理,因为有的视频没有片源,导致在抓取的时候会报错,加一个异常测试可以自动跳过没有片源的视频继续爬取有片源的视频。

总结

视频的名字和url都保存进了以视频名字命名的text文件中。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1659794.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于FPGA实现的HDMI TO MIPI扩展显示器方案

FPGA方案,HDMI IN接收原始HDMI 信号,输出显示到LCD 屏上 客户应用:扩展显示器 主要特性: 1.支持2K以下任意分辨率显示 2.支持OSD 叠加多个图层 3.支持MIPI/EDP/LVDS/RGB屏 4.支持放大缩小匹配屏分辨率 5.零延时,输…

从零学算法42

42.接雨水 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 示例 1: 输入:height [0,1,0,2,1,0,1,3,2,1,2,1] 输出:6 解释:上面是由数组 [0,1,0,2,1,0,1,3…

蚂蚁面试:DDD外部接口调用,应该放在哪一层?

尼恩说在前面: 在40岁老架构师 尼恩的读者交流群(50)中,最近有小伙伴拿到了一线互联网企业如字节、阿里、滴滴、极兔、有赞、希音、百度、网易、美团的面试资格,遇到很多很重要的面试题: DDD 的外部接口调用,应该放在…

Java方法和数组

方法 Java中的方法就是c语言中的函数。 方法的定义 定义格式如下 修饰符 返回值 方法名([参数列表]){代码块[return 返回值;] } //方括号[]括起来代表可以没有,不是必须有的方法名采用小驼峰命名(就是有多个单词,第一个单词首字母小写其…

阅读送书抽奖?玩转抽奖游戏,js-tool-big-box工具库新上抽奖功能

先讨论一个问题,你做软件工作是为了什么?从高中选专业,就喜欢上了软件开发?还是当初毕业不知道干啥,不喜欢自己的专业,投入软件开发的怀抱?还是干着干着别的,突然觉得互联网行业真不…

前端技术交流群

欢迎来到前端筱园用户交流!这是一个专注于前端编程技术、学习资源和行业动态的讨论平台。在这里,你可以分享经验、提问、回答问题,与其他前端开发者一起学习和成长。 🌟亲爱的朋友们🌟 大家好!感谢你们一直…

《Tam》论文笔记(下)

3 Method 3.1. The Overview of Temporal Adaptive Module 正如我们在第1节中讨论的,视频数据通常表现出由相机运动和速度变化等因素引起的复杂时间动态。因此,我们的目标是通过引入具有视频特定内核的时间自适应模块 (TAM) 来解决这个问题&#xff0c…

一键自动化博客发布工具,用过的人都说好(infoq篇)

infoq的博客发布界面也是非常简洁的。首页就只有基本的标题,内容和封面图片,所以infoq的实现也相对比较简单。 一起来看看吧。 前提条件 前提条件当然是先下载 blog-auto-publishing-tools这个博客自动发布工具,地址如下:https://github.c…

营收如泡沫,利润如刀片,万辰集团万店梦想下的阴影

(作者注:本文建议配乐《泡沫》阅读!) 从“食用菌第一股”转型为“量贩零食第一股”的首个财年,万辰集团新业务发展迅猛。 财报显示,2023年公司量贩零食业务实现营业收入87.59亿元,同比增长1305…

微火全域运营平台的优缺点分别是什么?

随着全域运营赛道的兴起,微火全域运营平台在市场占有率持续走高,与之相关的各类问题也层出不穷。其中,微火全域运营平台是什么、微火全域运营平台的优缺点等与平台本身相关的问题长期位居话题榜前列。 所谓微火全域运营平台,就是由…

京东手势验证码-YOLO姿态识别+Bézier curve轨迹拟合

这次给老铁们带来的是京东手势验证码的识别。 目标网站:https://plogin.m.jd.com/mreg/index 验证码如下图: 当第一眼看到这个验证码的时候,就头大了,这玩意咋识别??? 静下心来细想后的一个方案&#xf…

使用apache和htaccess对目录访问设置密码保护配置教程

对目录设置密码保护配置说明 我们有时候访问某些网站的时候,要求输入用户名和密码才能访问。这是为了保护隐私,只让经过许可的人访问。 在本教程中主要介绍两种方法,一种是通过apache httpd.conf配置文件对管理后台目录设置密码保护&#xff…

ESP32引脚入门指南(四):从理论到实践(PWM)

引言 ESP32 作为物联网领域的明星微控制器,除了强大的Wi-Fi和蓝牙功能,还内置了丰富的外设资源,其中就包括高级的PWM(脉冲宽度调制)功能。本文将深入探讨ESP32的PWM引脚,解析其工作原理,并通过…

分布式与一致性协议之Quorum NWR算法

Quorum NWR算法 概述 不知道你在工作中有没有遇到过这样的事情:你开发实现了一套AP型分布式系统,实现了最终一致性,且业务接入后运行正常,一切看起来都那么美好。 可是突然有同事说,我们要拉这几个业务的数据做实时分析&#xf…

进口原装二手 Keysight86142B 是德86142A 高性能光谱分析仪

进口原装二手 Keysight86142B 是德86142A 高性能光谱分析仪 内置测试应用程序 • 10 pm 波长精度 • 快速双扫法 • 覆盖 S、C 和 L 波段 Keysight 86142B是一款台式光谱分析仪(OSA),最适于对功率和波长精度、动态范围和低偏振敏感性都要…

asp.net论坛指南系统

说明文档 运行前附加数据库.mdf(或sql生成数据库) 主要技术: 基于asp.net架构和sql server数据库 登陆可查看 浏览记录 TA的发布 TA的回复 TA的收藏 TA的点赞 管理员登陆可以查看举报管理 编辑管理 认证审核 帖子置顶申请审核 运行环境…

【数据处理系列】深入理解递归特征消除法(RFE):基于Python的应用

目录 一、递归特征消除法介绍 二、方法介绍 三、导入数据并选择模型 (一)导入数据 (二) 递归特征消除需要选择模型吗 四、RFE方法进行递归特征消除法 五、RFECV方法进行递归特征消除法(建议使用这种方法) 即交叉验证递归特征消除法 (一)参数介绍 (二)python使用RFECV…

我们真的需要5G吗?再读《5G将是一个彻底的失败通信技术》

目录 投入与产出不成正比 《5G将是一个彻底的失败通信技术》 无线通信技术体制 无线通信技术演进 5G需求 移动通信与WiFi 5G之局 未来之路 参考 投入与产出不成正比 2018年开始大规模装备5G设备,因此2018年被称为5G元年。一般5G基站的寿命为8年左右&#…

GeoServer 任意文件上传漏洞分析研究 CVE-2023-51444

目录 前言 漏洞信息 代码审计 漏洞复现 前言 时隔半月,我又再一次地审起了这个漏洞。第一次看到这个漏洞信息时,尝试复现了一下,结果却很不近人意。从官方公布的漏洞信息来看细节还是太少,poc不是一次就能利用成功的。也是当时…

工器具管理(基于若依)

文章目录 前言一、工器具管理项目总览 二、入库功能1. 前端1.1 界面展示1.2 具体操作实现1.3 js文件 2. 后端2.1 工器具信息回显2.2 工器具入库 三、领用功能1. 前端1.1 界面展示1.2 具体实现操作1.3 js文件 2. 后端2.1 工器具信息回显2.2 工器具领用 遇到的问题1. 同一页面展示…