网站pc开发上海,工信部网站域名备案查询,贴吧高级搜索,庄河网站建设文章目录 一#xff0e;目标1.主站2.目标 二#xff0e;分析1.完整流程2.代码流程 三#xff0e;重点四#xff0e;源代码五#xff0e;总结 好久没有发表爬虫的博文了#xff0c;其实爬虫一直都有写#xff0c;只不过没有记录罢了。本次详细分析一个海外视频网站#… 文章目录 一目标1.主站2.目标 二分析1.完整流程2.代码流程 三重点四源代码五总结 好久没有发表爬虫的博文了其实爬虫一直都有写只不过没有记录罢了。本次详细分析一个海外视频网站抓取其中最高画质的视频撰写本篇博文记录完整分析过程。
一目标
1.主站 https://watchmovie.ac/ 这个网站的视频内容丰富直接就能访问里边的内容包括并不限于电影、电视剧、动漫。
2.目标
本次以电视剧为入口一步步分析每一层、每个接口的获取最终拿到视频的最高画质地址下载视频。
二分析
1.完整流程
打开一集电视剧点击播放按钮视频开始播放。 https://watchmovie.ac/series/roswell-new-mexico-season-4-episode-11 点击视频下方的下载按钮
来到了下载中间页在这个页面可以选择不同的源我这里直接选择了第三个因为相对其他三个简单。 https://membed.net/download?idMzY3NzAxtitleRoswell%2CNewMexico±Season4Episode11±FollowYouDowntypesubSUBsubL3Jvc3dlbGwtbmV3LW1leGljby1zZWFzb24tNC1lcGlzb2RlLTExLWZvbGxvdy15b3UtZG93bi9yb3N3ZWxsLW5ldy1tZXhpY28tc2Vhc29uLTQtZXBpc29kZS0xMS1mb2xsb3cteW91LWRvd24udjEudnR0coverY292ZXIvcm9zd2VsbC1uZXctbWV4aWNvLXNlYXNvbi00LnBuZwcaaaaaaaareferhttps://watchmovie.ac/ 点击第三个按钮来到了视频下载页面这个封面有点哲学。 https://embedsito.com/f/lnjz2fnmxd1zk53#captionhttps://msubload.com/sub/roswell-new-mexico-season-4-episode-11-follow-you-down/roswell-new-mexico-season-4-episode-11-follow-you-down.v1.vtt 点击左侧下载按钮等待10秒钟出现了下面的页面
其实在这个过程中向服务器发送了一个POST请求地址为 https://embedsito.com/api/source/lnjz2fnmxd1zk53 其实这两个地址是从接口返回的数据中拿到的
直接选择一个清晰度点击按钮就跳到了MP4播放页面 这个MP4地址是能够粘贴到迅雷里直接下载的清晰度也可以。 国内下载确实不怎么快。
2.代码流程
先放一个我自己的分析草图 放一张完整分析流程图
三重点
在分析过程中发现此网站很多网页都存在JS监控开发者工具的代码即当你打开了开发者工具网页会给予提示甚至直接隐藏或者跳转。
或者
所以在分析过程中还是要借助一下抓包工具比如在分析最后一个页面的接口时我用到了Fiddler。 在JS中发现了POST中的API地址。 直接获取所有的下载地址存储到数组然后按索引取-1拿到最高画质
四源代码
# coding:utf-8
import requests
import json
from lxml import etree
import reclass WatchMovieSpider(object):def __init__(self, url):super(WatchMovieSpider, self).__init__()self.normal_headers {user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36}self.base_url urlself.watchMovie_domain https://watchmovie.acdef do_request(self, url, headers, json_flagFalse):携带headers发送请求到url返回值类型可以是html也可以是jsontry:r requests.get(url, headersheaders)if r.status_code 200:html r.textif json_flag:_json_data json.loads(html)return _json_dataelse:return htmlreturn Falseexcept:return Falsedef get_all_eps_link_and_name(self, ):根据用户输入的电视剧、动漫获取其下所有剧集的地址if not self.base_url.endswith(/):all_eps_page_link self.base_url /seasonhtml self.do_request(all_eps_page_link, self.normal_headers)if html:res etree.HTML(html)selector res.xpath(//div[classmain-inner]//ul[classvideo_module carousel]/li//div[classvid_info]/span[1])data_list []for index, each in enumerate(selector):item {}title each.xpath(./a[classvideoHname]/title)if title:video_ep_title title[0]else:video_ep_title eps{}.format(index)link each.xpath(./a[classvideoHname]/href)if link:video_ep_link self.watchMovie_domain link[0]else:video_ep_link item[video_ep_title] video_ep_titleitem[video_ep_link] video_ep_linkdata_list.append(item)data_list.reverse() # 反转列表 使得电视剧集从小到大排列return data_listreturn Falsedef get_downloadPage_link(self, ep_link):根据主站获取iframe地址:return:html self.do_request(ep_link, headersself.normal_headers)if html:iframe_link re.findall(iframe src(.*?).*?/iframe, html)if iframe_link:iframe_real_link https: iframe_link[0]donwloadPage_link iframe_real_link.replace(streaming.php, download)return donwloadPage_linkreturn Falsedef get_postApi_addr(self, donwloadPage_link):访问根据下载页面解析出【第三个按钮】的地址使用字符串拼接拼接出视频下载接口地址:return:html self.do_request(donwloadPage_link, headersself.normal_headers)if html:res etree.HTML(html)aim_link res.xpath(//div[classmirror_link]/div[classdowload]/a[text()Download Xstreamcdn]/href)if aim_link:apiString aim_link[0].split(#)[0].split(/)[-1]postApi https://embedsito.com/api/source/ apiStringreturn postApielse:# 设置一个提取Btn3的备选方案print(使用plan2)# 先提取出所有的地址再使用字符串匹配all_btn_links res.xpath(//div[classmirror_link]/div[classdowload]/a/href)if all_btn_links:aim_link [l for l in all_btn_links if l.startswith(https://embedsito.com)]if aim_link:apiString aim_link[0].split(#)[0].split(/)[-1]postApi https://embedsito.com/api/source/ apiStringreturn postApireturn Falsedef get_movie_downloadAddr(self, postApi):根据postApi获取真正的视频下载地址:param postApi::return:try:r requests.post(postApi, headersself.normal_headers)if r.status_code 200:_json_data r.json()movie_high_addr self.parse_movie_high(_json_data)real_mp4_link self.get_redirect_after_addr(movie_high_addr)return real_mp4_linkreturn Falseexcept:return Falsedef parse_movie_high(self, _json_data):根据_json_data解析出画质最高的电影:param _json_data::return:data _json_data.get(data)print(- * 50)movie_high_addr data[-1].get(file)return movie_high_addrdef get_redirect_after_addr(self, link):获取重定向之后真实的mp4播放地址r requests.get(link, headersself.normal_headers, allow_redirectsFalse) # 禁止重定向拿到真实的mp4地址if r.status_code 302: # 获取重定向之后的真实mp4视频地址return r.headers.get(Location)elif r.status_code 200:return r.urlelse:return Falsedef video_name_format(self, name_str, ep):将电视剧名称转化为指定格式的名称# 正则提取一下剧名ep_name re.findall(Episode (.*?)$, name_str)if ep_name:eps_name_sp ep_name[0].strip().split( )eps_name_sp.pop(0)eps_name .join(eps_name_sp)else:if - in name_str:eps_name name_str.split(-)[-1].strip()else:eps_name tv_eps re.findall(Season \d Episode(\d) -, name_str)if tv_eps:eps_num tv_eps[0]else:eps_num epeps_name eps_name.replace(-, ).strip()full_ep_name Eps {}: {}.format(eps_num, eps_name)if full_ep_name.strip().endswith(:):final_tv_name full_ep_name.split(:)[0]else:final_tv_name full_ep_namereturn final_tv_namedef main():all_eps_link_name spider.get_all_eps_link_and_name()print(ep_sum, len(all_eps_link_name))for index, video_item in enumerate(all_eps_link_name):result {}video_each_name video_item[video_ep_title]result[name] spider.video_name_format(video_each_name, index 1)video_each_link video_item[video_ep_link]downloadPage_link spider.get_downloadPage_link(video_each_link) # downloadPage_link下载页面的地址包含四个按钮postApi spider.get_postApi_addr(downloadPage_link)if postApi:real_mp4_link spider.get_movie_downloadAddr(postApi)if real_mp4_link:result[link] real_mp4_linkelse:result[link] else:result[link] print(没有解析出视频下载接口)print(result)if __name__ __main__:lnik https://watchmovie.ac/series/the-amazing-race-canada-season-8if lnik.startswith(http) or lnik.startswith(https):spider WatchMovieSpider(lnik)main()else:print(输入地址不合法)
五总结
本次分析了一个海外视频网站着重在于爬虫的分析思路因为这会直接影响代码的撰写。发表本篇记录一下分析过程也为其他的道友踩踩坑。思路、代码方面有什么不足欢迎各位大佬指正、批评