首页 编程教程正文

tk & json 做的GUI 人人影视下载资源解析 改进版

piaodoo 编程教程 2020-02-22 22:16:43 1273 0 python教程

本文来源吾爱破解论坛

本帖最后由 anyedefeng 于 2020-1-19 15:33 编辑

首先感谢大佬@ liuhu1210 提供的人人影视的破解方案:https://www.52pojie.cn/thread-1003791-1-1.html
之后感谢大佬@bluerabbit 提供的UI交互形式,要简洁了很多:https://www.52pojie.cn/thread-1006124-1-1.html
在@bluerabbit 的基础上,我做了以下修正:
bugfix:
连续搜索多个影视剧可能会出现莫名弹窗的问题对于有多季的影视剧,其集数显示不正确的问题检索列表增加横向滚动条
功能提升:
搜索的影视剧后带出版年份,或者显示“暂无资源”以进行提示。比如搜索“傲慢与偏见”,年份可以提示这是哪一个版本的剧。资源显示时同时显示该资源的来源资源不再显示yyets链接,这个对于不使用客户端的人来说没用。


截图如下:红框为相对于@bluerabbit大佬功能提升部分。

QQ浏览器截图20200115172132.png (44.86 KB, 下载次数: 1)

下载附件  保存到相册

2020-1-19 15:10 上传



需要注意的一点是,为了增加年份信息,搜索时间会变长一些,因此可能会出现短暂的“卡死”现象,一般不超过10秒
以下是源码:
[Python] 纯文本查看 复制代码
from tkinter import *
import tkinter.messagebox as messagebox
import requests
import json
import pyperclip
import re

"""人人影视下载资源解析"""

def WriteDict(dicts,txt="a.txt"):
    """
    debug用的打印字典到文本文档
    """
    with open(txt,'w') as fout:
        for k,v in dicts.items():
            fout.write(str(k)+':'+str(v)+'\n')

class YYets:

    def __init__(self, master):
        self.master = master
        self.headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0'}
        self.api_search = 'http://pc.zmzapi.com/index.php?g=api/pv3&m=index&client=5&accesskey=519f9cab85c8059d17544947k361a827&a=search&uid=&token=&page=1&limit=30&k='
        self.api_get = 'http://pc.zmzapi.com/index.php?g=api/pv3&m=index&client=5&accesskey=519f9cab85c8059d17544947k361a827&a=resource&uid=undefined&token=undefined&id='
        self.listboxes = {}
        self.initWidgets()

    def initWidgets(self):
        """
        初始化GUI布局
        """
        #影剧搜索框、影剧搜索结果提示
        frame = Frame(self.master)
        frame.pack(expand=True, fill=BOTH, padx=10, pady=10, side=TOP)
        self.entry = Entry(frame, width=30, font=('simkai', 12), foreground='red')
        self.entry.pack(expand=True, fill=X, padx=0, pady=0, side=LEFT)
        self.entry.bind('<Return>', self.searchDrama)
        self.entry.insert(0, '关键词')
        self.entry.selection_range(0, END)
        self.entry.focus_set()
        self.sr = StringVar()#这一变量变化时便可在GUI上立即显示
        Label(frame, textvariable=self.sr, background='green', foreground='white', font=('simkai', 12), width=16, justify=CENTER).pack(expand=True, fill=X, padx=30, pady=0, side=LEFT)
        #影剧搜索详细结果
        frame = Frame(self.master)
        frame.pack(expand=True, fill=BOTH, padx=10, pady=0, side=TOP)
        self.srlist = StringVar()
        listbox = Listbox(frame, listvariable=self.srlist, background='lightgreen', font=('simkai', 12), exportselection=False)
        listbox.bind('<Double-Button-1>', self.chooseDrama)
        listbox.bind('<Return>', self.chooseDrama)
        #y滚动条
        scrollbar = Scrollbar(frame)
        scrollbar.pack(fill=Y, padx=0, pady=0, side=RIGHT)
        listbox.config(yscrollcommand=scrollbar.set)
        scrollbar.config(command=listbox.yview)
        #x滚动条
        scrollbar = Scrollbar(frame, orient=HORIZONTAL)
        scrollbar.pack(fill=X, padx=0, pady=0, side=BOTTOM)
        listbox.config(xscrollcommand=scrollbar.set)
        scrollbar.config(command=listbox.xview)
        listbox.pack(expand=True, fill=BOTH, padx=0, pady=0, side=LEFT)
        self.listboxes['drama'] = listbox
        #影剧季集title
        self.videotitle = StringVar()
        Label(self.master, textvariable=self.videotitle, background='green', foreground='white', font=('simkai', 12), justify=CENTER).pack(expand=True, fill=X, padx=10, pady=10, side=TOP)
        #季、集、资源选择
        topframe = Frame(self.master)
        topframe.pack(expand=True, fill=BOTH, padx=10, pady=0, side=TOP)
        #季
        frame = Frame(topframe)
        frame.pack(expand=True, fill=BOTH, padx=0, pady=0, side=LEFT)
        self.seasonlist = StringVar()
        listbox = Listbox(frame, listvariable=self.seasonlist, background='lightgreen', font=('simkai', 10), width=10, exportselection=False)
        listbox.pack(expand=True, fill=BOTH, padx=0, pady=0, side=LEFT)
        listbox.bind('<Double-Button-1>', self.chooseSeason)
        listbox.bind('<Return>', self.chooseSeason)
        scrollbar = Scrollbar(frame)
        scrollbar.pack(fill=Y, padx=0, pady=0, side=RIGHT)
        listbox.config(yscrollcommand=scrollbar.set)
        scrollbar.config(command=listbox.yview)
        self.listboxes['season'] = listbox
        #集
        frame = Frame(topframe)
        frame.pack(expand=True, fill=BOTH, padx=10, pady=0, side=LEFT)
        self.episodelist = StringVar()
        listbox = Listbox(frame, listvariable=self.episodelist, background='lightgreen', font=('simkai', 10), width=10, exportselection=False)
        listbox.pack(expand=True, fill=BOTH, padx=0, pady=0, side=LEFT)
        listbox.bind('<Double-Button-1>', self.chooseEpisode)
        listbox.bind('<Return>', self.chooseEpisode)
        scrollbar = Scrollbar(frame)
        scrollbar.pack(fill=Y, padx=0, pady=0, side=RIGHT)
        listbox.config(yscrollcommand=scrollbar.set)
        scrollbar.config(command=listbox.yview)
        self.listboxes['episode'] = listbox
        #资源
        frame = Frame(topframe)
        frame.pack(expand=True, fill=BOTH, padx=0, pady=0, side=LEFT)
        self.srclist = StringVar()
        listbox = Listbox(frame, listvariable=self.srclist, background='lightgreen', font=('simkai', 10), width=50, height=14, exportselection=False)
        listbox.bind('<Double-Button-1>', self.copySrc)
        listbox.bind('<Return>', self.copySrc)
        scrollbar = Scrollbar(frame)
        scrollbar.pack(fill=Y, padx=0, pady=0, side=RIGHT)
        listbox.config(yscrollcommand=scrollbar.set)
        scrollbar.config(command=listbox.yview)
        scrollbar = Scrollbar(frame, orient=HORIZONTAL)
        scrollbar.pack(fill=X, padx=0, pady=0, side=BOTTOM)
        listbox.config(xscrollcommand=scrollbar.set)
        scrollbar.config(command=listbox.xview)
        listbox.pack(expand=True, fill=BOTH, padx=0, pady=0, side=LEFT)
        self.listboxes['src'] = listbox
        #空白
        frame = Frame(self.master)
        frame.pack(expand=True, fill=BOTH, padx=10, pady=5, side=BOTTOM)

    def InitVariables(self):
        """
        每次搜索影视剧均要重新初始化变量
        """
        self.sr.set('')
        self.srlist.set('')
        self.videotitle.set('')
        self.seasonlist.set('')
        self.episodelist.set('')
        self.srclist.set('')

        self.idx = []

    def searchDrama(self, event):
        """
        搜索影视剧
        """
        if self.entry.get() == '':
            messagebox.showwarning(sys._getframe().f_code.co_name, '关键词缺失')
        else:
            self.InitVariables()
            try:
                response = requests.get(self.api_search+self.entry.get(), headers=self.headers)
                if response.status_code != 200:
                    response.raise_for_status()
            except Exception as e:
                messagebox.showwarning('影视', e)
            else:
                #获取所有的结果
                result = json.loads(response.text)
                #生成结果list
                self.ids = list(map(lambda i: result['data'][i]['id'], range(len(result['data']))))
                self.ReqSources()
                self.sr.set('查询结果:%d项' % len(result['data']))
                self.srlist.set(list(map(lambda i: '%d.[%s].%s (%s),%s' % (i, result['data'][i]['channel_cn'], result['data'][i]['cnname'], result['data'][i]['enname'],self.dates[i]), range(len(result['data'])))))
                #如果列表中只有一项,则自动选中
                if self.listboxes['drama'].size() == 1:
                    self.listboxes['drama'].selection_set(0)
                    self.chooseDrama()

    def ReqSources(self):
        """
        获取所有搜索结果的页面
        """
        sources = {}
        dates = {}
        for idx,drama_id in enumerate(self.ids):
            try:
                response_drama = requests.get(self.api_get+str(drama_id), headers=self.headers)
                if response_drama.status_code != 200:
                    response_drama.raise_for_status()

            except Exception as e:
                messagebox.showwarning(sys._getframe().f_code.co_name, e)
            else:
                #获取该影视剧的页面
                result_drama = json.loads(response_drama.text)
                sources[idx]=result_drama
                #获取该影视剧的年份
                if result_drama['info'] in ['暂无资源', '资源关闭']:
                    dates[idx]=result_drama['info']
                else:
                    try:
                        date=result_drama['data']['detail']['premiere']
                    except Exception as e:
                        messagebox.showwarning(sys._getframe().f_code.co_name, e)
                    else:
                        result = re.match(r'\d\d\d\d',date)
                        if result:
                            dates[idx]=result.group()
                        else:
                            dates[idx]=''
        self.sources = sources
        self.dates = dates

    def chooseDrama(self, event='<Double-Button-1>'):
        """
        选择影视剧后读取页面,并打印季数
        """
        try:
            drama_chosen = self.listboxes['drama'].get(self.listboxes['drama'].curselection())
        except:
            messagebox.showwarning(sys._getframe().f_code.co_name, '未选择影剧')
        else:
            self.seasonlist.set('')
            self.episodelist.set('')
            self.srclist.set('')
            dramma_idx = int(drama_chosen[:drama_chosen.index('.')])
            self.drama = drama_chosen[drama_chosen.index('.')+1:]
            self.videotitle.set(self.drama)
            result_drama = self.sources[dramma_idx]
            self.parseDrama(result_drama)

    def parseDrama(self, result_drama):
        """
        解析该影视剧,并将影视剧的信息放入列表中
        """
        if result_drama['info'] in ['暂无资源', '资源关闭']:
            messagebox.showwarning(sys._getframe().f_code.co_name, result_drama['info'])
            return
        season_names = []
        self.season_episodes = {}
        self.src = {}
        try:
            for dics in result_drama['data']['list']:
                episode_names = [] #对每季均要初始化episode_names
                episodes = dics['episodes']
                if episodes:
                    #正常情况,episodes是一个列表
                    #特殊情况,"episodes": null,则跳过
                    season_name = dics['season_name']
                    season_names.append(season_name)
                    for j in range(len(episodes)):
                        episode_name = episodes[j]['episode_name']
                        episode_names.append(episode_name)
                        self.src[season_name+episode_name] = []
                        files = episodes[j]['files']
                        for fileformat in files:
                            #yyets使用客户端就可以了,因此没必要显示yyets的链接
                            if fileformat != 'yyets':
                                for filesrc in files[fileformat]:
                                    way_name = filesrc['way_name']
                                    way_name = '[%s]:'%way_name
                                    src_address = filesrc['address']
                                    src_passwd = filesrc['passwd']
                                    if src_passwd:
                                        self.src[season_name+episode_name].append(way_name+src_address + '   pw: ' + src_passwd)
                                    else:
                                        self.src[season_name+episode_name].append(way_name+src_address)
                        self.season_episodes[season_name] = episode_names
            self.seasonlist.set(season_names)
            #如果列表中只有一项,则自动选中
            if self.listboxes['season'].size() == 1:
                self.listboxes['season'].selection_set(0)
                self.chooseSeason()
        except Exception as e:
            messagebox.showwarning(sys._getframe().f_code.co_name, e)

    def chooseSeason(self, event='<Double-Button-1>'):
        """
        选择季后打印集数
        """
        try:
            #这里,不应该用self.listboxes['season'].get(ACTIVE)语句,
            #  是因为在搜索上一个影视剧时该ACTIVE数值会被改掉,
            #  而在搜索下一个影视剧时可能仅有1季,会在未经过双击时自动触发chooseSeason.
            self.season_chosen = self.listboxes['season'].get(self.listboxes['season'].curselection())
        except:
            messagebox.showwarning(sys._getframe().f_code.co_name, '未选择“季”')
        else:
            self.episodelist.set('')
            self.srclist.set('')
            self.videotitle.set(self.drama + '.' + self.season_chosen)
            self.episodelist.set(self.season_episodes[self.season_chosen])
            #如果列表中只有一项,则自动选中
            if self.listboxes['episode'].size() == 1:
                self.listboxes['episode'].selection_set(0)
                self.chooseEpisode()

    def chooseEpisode(self, event='<Double-Button-1>'):
        """
        选择集数后打印下载链接
        """
        try:
            episode_chosen = self.listboxes['episode'].get(self.listboxes['episode'].curselection())
        except:
            messagebox.showwarning(sys._getframe().f_code.co_name, '未选择“集”')
        else:
            self.srclist.set('')
            self.videotitle.set(self.drama + '.' + self.season_chosen + '.' + episode_chosen)
            if self.src[self.season_chosen+episode_chosen]:
                self.srclist.set(self.src[self.season_chosen+episode_chosen])
            else:
                self.srclist.set('未发现下载资源')

    def copySrc(self, event='<Double-Button-1>'):
        """
        拷贝下载链接到剪贴板
        """
        try:
            src_chosen = self.listboxes['src'].get(self.listboxes['src'].curselection())
        except:
            messagebox.showwarning(sys._getframe().f_code.co_name, '未选择资源')
        else:
            #下载链接去掉way_name
            if src_chosen=='未发现下载资源':
                messagebox.showwarning(sys._getframe().f_code.co_name, '未发现下载资源')
            else:
                re_match = re.match(r'\[.*?\]:(.*)',src_chosen)
                downlink = re_match.group(1)

                #拷贝到剪贴板
                pyperclip.copy(downlink)
                messagebox.showinfo(sys._getframe().f_code.co_name, '%s\n\n已复制至剪贴板' % downlink)

if __name__ == '__main__':
    root = Tk()
    root.resizable(width=False, height=False)
    root.title('人人影视下载资源解析')
    YYets(root)
    root.update_idletasks()
    width, height = (root.winfo_width(), root.winfo_height())
    screenwidth, screenheight = (root.winfo_screenwidth(), root.winfo_screenheight())
    size_loc = '%dx%d+%d+%d' % (width, height, (screenwidth-width)/2, (screenheight-height)/2-30)
    root.geometry(size_loc)
    root.mainloop()


嗨学网 人人影视下载.zip (3.71 KB, 下载次数: 130) 2020-1-19 15:15 上传 点击文件名下载附件
源码
下载积分: 吾爱币 -1 CB




版权声明:

本站所有资源均为站长或网友整理自互联网或站长购买自互联网,站长无法分辨资源版权出自何处,所以不承担任何版权以及其他问题带来的法律责任,如有侵权或者其他问题请联系站长删除!站长QQ754403226 谢谢。

有关影视版权:本站只供百度云网盘资源,版权均属于影片公司所有,请在下载后24小时删除,切勿用于商业用途。本站所有资源信息均从互联网搜索而来,本站不对显示的内容承担责任,如您认为本站页面信息侵犯了您的权益,请附上版权证明邮件告知【754403226@qq.com】,在收到邮件后72小时内删除。本文链接:http://www.piaodoo.com/8080.html

评论

搜索