注:本人小白一枚,爬虫也是刚接触,写的不好请多指点
这里只给出前部分,获取m3u8视频的方法,转换格式下一节再给出
目录
网页分析
我们需要对网页进行一个分析,当我们鼠标变动时,这个网页的url会怎么变化
搜索页面
当在搜索框中搜索内容后发现
不管输入什么内容,它的搜索永远都是www.yhdm81.com/search.php,它是不会变化的
所以我们要对这个搜索页面做一番研究,在www.yhdm81.com/search.php页面上按下F12(单击右键点击检查也一样),进入开发者模式。找到网络(Network)然后ctrl+r刷新页面
在名称中将鼠标滑倒最顶端找到一个名字类似:
ssszz.php?top=10&q=ly&other_kkk217=%2568%2574%2574…68%2564%256d%2538%2531%252e%2563%256f%256d&dect=0
文件单击打开,显示其中的信息:
双击运行这个文件后是这样的:
结合上面的ssszz.php?top=10&q=ly(我将后面的一串删掉,发现ly就是我们输入的内容)
这就很好的印证了,右边一串请求的url才是真正请求的网址也就是:
http://159.75.0.62:11234/ssszz.php?top=10&q=
q后面是我们搜索的内容
介绍界面
在我们搜索完之后,随便点击一个影视,进入介绍界面:
在上面的url中能发现,在yhdm81.com后面多了一个/tv/74378,这串数字在之前的网站中也有
那我们要想打开这个介绍页面,那就得在域名的后面加上一串这个东西,所以我们要去获取这个
接下来是实现这个功能的代码:
import requests
import re
def parse_search_url(url):
"""
用于提取搜索网页的内容也就是http://159.75.0.62:11234/ssszz.php?top=10&q={}网页中的内容,{}中为搜索值
:param url: http://159.75.0.62:11234/ssszz.php?top=10&q={}
:return: detail_url返回解析后的url后缀,格式是/acq/74378类似的形式,movies_name返回影片名字
"""
headers = {
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.134 Safari/537.36 Edg/103.0.1264.71",
"Cookie":
"PHPSESSID=8jnc6i33n2lablu2arfqev17l7"
}
resp=requests.get(url,headers=headers)
html=resp.content.decode("utf-8")
detail_url=re.findall(".+(/acg/\d+/)",html) #这里不一定是acg,我找的是动漫内容
movies_name=re.findall(r"""title.+"(.+?)",""",html)
return detail_url,movies_name
视频页面
介绍页面之中,有选集我们点击进入就会到达视频界面
通过url和级数的对比可以看出,第一集对应1.html,以此类推
这个之后在选集的时候可以使用
然后就是去找这个视频文件在哪里,在源代码(Sources)中会找到一个d.gqyy8.com:8077的域名
发现在这个文件下的数字74378与先前的/tv/74378/是一致的,然后我们打开这个js文件
拿playarr_sn举例在[ ]中的数字表示了集数 ,而这个参数后面的一串https://后面的一系列都是视频的m3u8格式所在位置
接下来,我们对这个url进行提取:
def episodes(url):
"""
用于显示视频更新到哪一集
:param url: http://yhdm81.com/+后面的后缀,如:/tv/74378/
:return: 没有返回值,只是告知使用者该动画更新到第几集了
"""
headers={
"User-Agent":
"Mozilla / 5.0(Windows NT 10.0;Win64;x64) AppleWebKit / 537.36(KHTML, likeGecko) Chrome / 103.0.5060.134Safari / 537.36Edg / 103.0.1264.71"
}
resp = requests.get(url, headers=headers)
html = resp.content.decode("utf-8")
episodes_num = re.findall(r"""<span style="font-size:12px;margin-left:10px;">(\D.+)</span><span.+""", html)
print(f"目前{episodes_num[0]}")
def true_video_web(video_num,episode_num):
"""
获取视频的网络位置
:param video_num:视频的编号,如:/tv/74378/中的74378
:param episode_num: 选择的集数
:return: 返回获取到的m3u8地址
"""
headers={
"User-Agent":
"Mozilla / 5.0(Windows NT 10.0;Win64;x64) AppleWebKit / 537.36(KHTML, likeGecko) Chrome / 103.0.5060.134Safari / 537.36Edg / 103.0.1264.71"
}
playarr_url=f"http://d.gqyy8.com:8077/ne2/s{video_num}.js"
resp = requests.get(playarr_url, headers=headers)
html = resp.content.decode("utf-8")
video_m3u8=re.findall(r"""playarr_.{1,3}\[\d\]="https://.+\.m3u8""",html)
#video_url=f"https://yun.66dm.net/SBDM/{video_m3u8[0][:-1]}{episode_num}.m3u8"
#以上两行代码是基于爬取的视频是漫画的前提下写的
m3u8_url_list=video_m3u8[0].split(";")
m3u8_url_episode=m3u8_url_list[episode_num-1]
m3u8=re.findall("https.+\.m3u8",m3u8_url_episode)
return m3u8[0]
最终代码
import requests
import re
def parse_search_url(url):
"""
用于提取搜索网页的内容也就是http://159.75.0.62:11234/ssszz.php?top=10&q={}网页中的内容,{}中为搜索值
:param url: http://159.75.0.62:11234/ssszz.php?top=10&q={}
:return: detail_url返回解析后的url后缀,格式是/acq/74378类似的形式,movies_name返回影片名字
"""
headers = {
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.134 Safari/537.36 Edg/103.0.1264.71",
"Cookie":
"PHPSESSID=8jnc6i33n2lablu2arfqev17l7"
}
resp=requests.get(url,headers=headers)
html=resp.content.decode("utf-8")
#print(html)
detail_url=re.findall(".+(/.+/\d+/)",html)
movies_name=re.findall(r"""title.+"(.+?)",""",html)
return detail_url,movies_name
def episodes(url):
"""
用于显示视频更新到哪一集
:param url: http://yhdm81.com/+后面的后缀,如:/tv/74378/
:return: 没有返回值,只是告知使用者该动画更新到第几集了
"""
headers={
"User-Agent":
"Mozilla / 5.0(Windows NT 10.0;Win64;x64) AppleWebKit / 537.36(KHTML, likeGecko) Chrome / 103.0.5060.134Safari / 537.36Edg / 103.0.1264.71"
}
resp = requests.get(url, headers=headers)
html = resp.content.decode("utf-8")
episodes_num = re.findall(r"""<span style="font-size:12px;margin-left:10px;">(\D.+)</span><span.+""", html)
print(f"目前{episodes_num[0]}")
def true_video_web(video_num,episode_num):
"""
获取视频的网络位置
:param video_num:视频的编号,如:/tv/74378/中的74378
:param episode_num: 选择的集数
:return: 返回获取到的m3u8地址
"""
headers={
"User-Agent":
"Mozilla / 5.0(Windows NT 10.0;Win64;x64) AppleWebKit / 537.36(KHTML, likeGecko) Chrome / 103.0.5060.134Safari / 537.36Edg / 103.0.1264.71"
}
playarr_url=f"http://d.gqyy8.com:8077/ne2/s{video_num}.js"
resp = requests.get(playarr_url, headers=headers)
html = resp.content.decode("utf-8")
video_m3u8=re.findall(r"""playarr_.{1,3}\[\d\]="https://.+\.m3u8""",html)
#video_url=f"https://yun.66dm.net/SBDM/{video_m3u8[0][:-1]}{episode_num}.m3u8"
#以上两行代码是基于爬取的视频是漫画的前提下写的
m3u8_url_list=video_m3u8[0].split(";")
m3u8_url_episode=m3u8_url_list[episode_num-1]
m3u8=re.findall("https.+\.m3u8",m3u8_url_episode)
return m3u8[0]
def open_web(url):
url_HLSPlayer="https://www.hlsplayer.net/#type=m3u8&src="+url.replace(":","%3A").replace("/","%2F")
return url_HLSPlayer
#这只是一个用来拼接url的函数,用来检查所爬取的与网站上的是否一致
def main():
search_url = "http://159.75.0.62:11234/ssszz.php?top=10&q={}".format(input("请输入你要搜索的内容:"))
urls,names=parse_search_url(search_url)
print(f"一共找到以下{len(names)}项内容:")
for name,num in zip(names,range(1,len(names)+1)):
print(f"第{num}项:","\t",f"{name}")
try:
choice=int(input("请选择你要找的影视片(输入数字即可):"))-1
except:
print("输入有误!")
movies_url="http://yhdm81.com/"+urls[choice]
print("注意:出现正片或备用,直接选择1即可")
episodes(movies_url)
episode_num=input("请选择你要的集数(输入数字即可):")
video_num=re.findall("/(acg|zongyi|tv|mov)/(\d.+)/",urls[choice])
print(open_web(true_video_web(video_num[0][1], int(episode_num))))
return true_video_web(video_num[0][1], int(episode_num))
if __name__ == '__main__':
main()
运行结果
感觉有点......有点啰嗦了,这个运行,算了就先这样吧。
欢迎评论!或提供更好的思路!