GUI小工具-网盘搜索器

0. 写在最前

此专栏是记录以下一些我自己在本科写的一些小工具,仅仅用作学习为目的,绝不会有任何盈利,如果损害到了开发者的利益,请立即联系我进行删除,本人邮箱:zh00612@126.com

1. 介绍

现在有很多的网盘网站,在搜索资源时往往是需要会员才能得到网盘资源的真实地址,但其实它里面的地址在包中是暴露的,仅仅是需要普通用户就可以得到资源,只需要的到里面的接口就可以了

2. 代码和功能展示

main.py

import threading
import PySimpleGUI as sg
from ui import main_layout, serach, win_icon, info_window
from luopanso import table_datas
import pyperclip

class UI():
    def __init__(self):
        self.top_window = sg.Window('网盘搜索神器v1.0', main_layout, finalize=True,
                                    grab_anywhere=False, alpha_channel=1, icon=win_icon)
        self.datas = [[]]

    def run_task(self):
        self.datas = table_datas(self.values.get('-input-'))
        self.top_window.write_event_value('-THREAD-', '*** The thread says.... "I am finished" ***')

    def circle_event(self):
        search_layout_active = False
        # 由于搜索时间过长,体验较差,因此通过多线程加入加载条
        # 线程标志位
        thread = None
        # 设置加载条刷新频率
        timeout = 100
        while True:
            # 循环读取窗口信息,事件和值
            self.event, self.values = self.top_window.read(timeout=100)

            # 如果触发关闭事件就关闭窗口
            if self.event in (sg.WIN_CLOSED, 'Exit'):
                break

            elif self.event == "serach" and not search_layout_active:
                if not self.values.get('-input-'):
                    sg.popup_error('请输入关键字再搜索!', keep_on_top=True)
                else:
                    thread = threading.Thread(target=self.run_task,
                                              daemon=True)
                    thread.start()
            if self.event == '-THREAD-':
                # 结束线程
                thread.join(timeout=0)
                # 结束加载条
                sg.popup_animated(None)
                # 清除标志位
                thread, timeout = None, None
                search_window = info_window(self.datas)
                search_layout_active = True

            if thread is not None:
                sg.popup_animated(sg.DEFAULT_BASE64_LOADING_GIF, background_color='white', transparent_color='white',
                                  time_between_frames=10, message='正在搜索网盘资源....', text_color="blue", font="5px")
            elif search_layout_active:
                search_event, search_value = search_window.read(timeout=1000)
                if search_event in (sg.WIN_CLOSED, 'Exit'):
                    search_layout_active = False
                    search_window.close()
                elif search_event == '_table_':
                    url = search_window['_table_'].get()[int(search_value['_table_'][0])][-1]
                    pyperclip.copy(url)
                    sg.popup_quick_message('url已经复制到剪切板!,请在浏览器打开', text_color='#2ecc71', font='3px', keep_on_top=True)

        self.top_window.close()


if __name__ == '__main__':
    ui = UI()
    ui.circle_event()

luopanso.py

import time
from dataclasses import dataclass
from typing import List

import requests


@dataclass
class Info(object):
    id: str
    filename: str
    update_time: str
    size: str


def get_millisecond():
    """
    :return: 获取精确毫秒时间戳,13位
    """
    millis = int(round(time.time() * 1000))
    return millis


def hum_convert(value) -> str:
    units = ["B", "KB", "MB",
             "GB", "TB", "PB"]
    size = 1024.0
    for i in range(len(units)):
        if (value / size) < 1:
            return "%.2f%s" % (value, units[i])
        value = value / size


class LuoPanSo(object):
    def __init__(self):
        self.headers = {
            "Accept": "application/json, text/plain, */*",
            "Accept-Language": "zh-CN,zh;q=0.9,en-GB;q=0.8,en;q=0.7",
            "Cache-Control": "no-cache",
            "Connection": "keep-alive",
            "Origin": "https://www.luomapan.com",
            "Pragma": "no-cache",
            "Referer": "https://www.luomapan.com/",
            "Sec-Fetch-Dest": "empty",
            "Sec-Fetch-Mode": "cors",
            "Sec-Fetch-Site": "cross-site",
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36",
            "X-Authorization": 你的cookie,
            "sec-ch-ua": "^\\^Google",
            "sec-ch-ua-mobile": "?0",
            "sec-ch-ua-platform": "^\\^Windows^^"
        }

    @property
    def c_time(self):
        millis = int(round(time.time() * 1000))
        return millis

    def get_info_list(self, key_str):
        url = "https://fc-resource-node-api.krzb.net/api/v1/pan/search"
        params = {
            "version": "v2",
            "kw": key_str,
            "page": 1
        }
        response = requests.get(url, headers=self.headers, params=params).json()
        return [Info(data['res']['id'], data['res']['filename'],
                     data['res']['updatetime'], hum_convert(int(data['res']['size'])))
                for data in response['resources']]

    def check_ok(self, data: Info):
        url = "https://fc-resource-node-api.krzb.net/api/v1/pan/checkUrlValidFromBaidu"
        params = {
            "t": self.c_time,
            "version": "v2",
            "data": data.id
        }
        response = requests.get(url, headers=self.headers, params=params).json()
        if response.get(data.id):
            return True

    def resource_detail(self, id):
        url = "https://fc-resource-node-api.krzb.net/api/v1/pan/detail"
        params = {
            "version": "v2",
            "id": id,
            "size": "15",
            "parent": ""
        }
        response = requests.get(url, headers=self.headers, params=params).json()
        if response.get('haspwd'):
            return response['pwd']
        return None

    def get_pan_url(self, id, pwd):
        url = "https://fc-resource-node-api.krzb.net/api/v1/pan/url"
        params = {
            "version": "v2",
            "id": id
        }
        response = requests.get(url, headers=self.headers, params=params).json()
        if pwd:
            return response['data'] + f'?pwd={pwd}'
        return response['data']


def table_datas(key_str: str) -> List[List]:
    TableDatas = []
    l = LuoPanSo()
    datas = l.get_info_list(key_str)
    for index, data in enumerate(datas):
        pwd = l.resource_detail(data.id)
        if l.check_ok(data):
            filename = data.filename
            size = data.size
            update_time = data.update_time
            pan_url = l.get_pan_url(data.id, pwd)
            TableDatas.append([index + 1, filename, size, update_time, pan_url])
    return TableDatas

ui

import PySimpleGUI as sg

serach = b'iVBORw0KGgoAAAANSUhEUgAAAB0AAAAdCAYAAABWk2cPAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAARcSURBVEhLvZZtUFRVGMf/vCi7G4ZA4CwiyovsophaEBNIKIwgyRq040CIVk7qaM1oM2ZrhrYTzUjJOBqNTfBBRsqKplGcUsmZPiSVgDloIhMLYoIQMPEOu3fv8nT27kHL3cVdRvt9uff8n+fc/71nnvuc40EM/M+4ZGo2jeJOezOEcROsyXKFHMpwFbxnKGwJbjKlaYfhKqo/K0FbUwu7b4AomGHN9pHLEBYdh/DFUVj90lZExD7LZ7iGU9Oq0t344lAJjCNA8rpUpObuYF/oC/IABnu7ceHkUdTV/AbfAKBg9z7k7CjiM13AavpvRgb66M1MNSXPAJUd2MJVx4gWMx3cupJWykDv5j5Do0ODPDI1dqZvZS0hzVzQjbpzXHkwZys+pMwgkP7lNDay2MQp+I/p6bJCWuHtnuEk1WVFlBEI+vroXq44565pV/t10oZ7UOmeDVxxH13OMnqBrdLocD9XHHPX9JhuE2UE2K22W9xsqqecMFC5fjNXHONpLSbBOATDtRYkZMRJxTVdFsTEITQ6CBdP/8gVx0im3e0GdLReRnreLkk0jw9J1+kQHhOPCcsQhvu7uGKP7UsFEyxmAf5zlPirpxerE+Ix1NcpJbhLxKLlGBvpR8/tVq7YI5lKF9YiRFHEnOAgnP21Ab7+wbaQm4hkAesf8PDysgkOkExlCh/MVCjQfcsgieWFr+ET3Ubp3l2a63+Cwi8QQaGRXLFHMg0JX4T5qgScP1EiiU+v0qD2zBn83d0tjd2ho+V3+MhmYZaf85WSTD29ZiJ6mRrXfm6DyTiKxKwCzFfHoHTPi1KSqzT8cJIV5SCSNFlccQL/dYjtKJSr8qZ9ubHS2GQcoPQAPzr0eqY0doW92udIEwISzeNcccx9bfB9WqUAfXtsP1eINscHUP7ieSSYhrnimOMfbKd0f9C5imKuOMeuBRW9mipNrvr4Ha4QXTpfSWbByEf2lOu3kTYKVBAL2rlGTb2dBh5xjJ2pYBLYdrWW0meD3s5eSm3X63jEnoYLX5FOm0K5alBloZL6GlX0ylNetCVJTX1drTzLHqeb+KkyPSqK3mMvBXZKeAJzo55EaCR7usWC9uZG3Gm7gY6bg5D7sl/OB9B9pEJMEsH4J7Ahy4CwhUtwoPJ7zA4M4U+8x5THFdFsRNURHWq+rGatbQTC2AArdU/I5P6QPSZHinY98nYVQ5cdh6aGy9B9GoHEZG+MsQ648fk/EKZaCv3nNXg84L7fx2rqCsMDPdTeXM+q/AoZRwe4OskEFW9fT5p5oEvfLCAaU1NnbTRpI8G2u0QSRRPPs+Gy6YMQRTPtz0+htUpQfXUkU9TUwYzTWG2UvJFtS+I8NNNJ9JvSKY3ty/WnItibqOj2L1GUEQxqvHjvNPLQTa0c3LaO1rAzU21lCH13WEmaMC+61XyFRx+RqSgKdHhnPuXF+pN2oZw1nSIeseHSCX86sFMhDFfrQBMWRC9fwVUbj8zUOcA/k7eHTRyafqUAAAAASUVORK5CYII='
win_icon = b'iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAAOXSURBVDhPjZRNbFRVFMd/72PmzXQ6hbbQ0tKhIBZsWqRQJNH4nSguuiDBuDJswIWJIYQalcSlqBE1Gq0Lqwti2OBCTcDErozBhAS1XwwkGIt0WtoObScz7cy8+XjzPO/OtNJSG38vN/fmfvzvOeee8zRX4D8YGktzfcImlSkSDhq0twTZvzNUWV2bNQVPfxOj/6c4fs3ApxvoaJRwKZQcCjI6/txm3jsaqexeyQrBv+M5Hn0jijdTr4dwtyVwts7jBgpoWR/GnVqMWD0Lrk0eh8vvt/NAY6ByusyyYOxujs4TowT8Oi92NXL5iQHmrSSGYyLGyU7pTAct46fq0j60iQ3E0mlGPt3D9kbLk1AsC0aODZIvuhwTd959OYL161mazGo0TZTuwdXE+bBNcGAP+nALC9jEvt5XWUXCI7xzYVKJPba7WokpStI8q1Z9ooiWCpJ9fhStOYle0jnz7WT5jKAE+36cIV9wOd/7oJr02F1XQ9HKqfjd14ISU9tH5oURagjy2cWZyikwb96xyYnYwV0hqiydG7Ese0+OsjP8FHW6uu8+tLxJ9tAI9sG/KG1JwoSPoVtpunaE0KPjGbXp6c4a1ZsGhAIGCTdDTiuAIb6vat7juNJrBZNiZF6lV3Q8Wz6ftr1gwcaQKAltzUES57vV+JGb/cRyKSzJxdVoOZ8IGrhWUcUtlXHUvF5bLWkhzC0UVX8vV3e9guQyriNHJPhazkRPB1TTinKJ5qJLfnpJXxcu65id24JqMDCU5O2Xti7H0HPbr+k0+HvkseXLG9iHRsl3TJbFBNfnSKLXkZNbH26tUnN6a4NFdUDn2u0sc6mCehhPzDI1dNNlrpRmtrTIrJsmLn3GKVB0xSa9hDEbRouH8fmhPVI2TCX2h99Pcfa7KVX8P59pVwtrMWhP8cX4ML8kx0lUJdl87llScZOThxvoPdyk9ixXSturwyxmHXoO1NL/2g61uB5v9s1w4Y8ZGusNrnzQUZmtJLbH7x91qmq5+FuCx9+6zm2p7fX46soEliUhSRW5K6FaYsXfxrPwwOtREvLiBcelrSnAkx1hNlYbnD7SjK7/W9e3Zmy6T0Vp2GCqDLnRt5dNNeZKwSU+vzTNxz9Mk0g7eBqJxSKfHG/lRM+Wyo4yY9Mi2hulUURnxdLpc/vXFlxiXNweHMuQlKQ9+symyuxK/pTS7T51jUXbYezLrvUF/y/z4nI8WeChliD/AAH0pMxCJYwVAAAAAElFTkSuQmCC'
# 改变主题
sg.ChangeLookAndFeel('Default1')


# 装饰按钮
def GraphicButton(text: str, key: str, image_data):
    text = text.replace('_', ' ')
    button = sg.Button('', image_data=image_data, button_color=('white', '#F1F1F1'), font='Any 15', key=key,
                       border_width=1)
    text = sg.Text(text, font='Any 10', size=(15, 1), justification='center', )
    return sg.Column([[button], [text]], element_justification='c')


main_layout = [[sg.T('搜索关键字:', font="15px"),
                sg.Input(key='-input-', text_color='blue', size=(12, 100),
                         font="15px"), sg.Button(key='serach', image_data=serach)]]


def info_window(datas) -> sg.Window:
    """
    :return: 返回一个sg的window对象
    """
    info_layout = [[sg.Table(
                       values=datas,
                       headings=['序号', '文件名', '文件大小', '更新时间', '网盘地址(左键单击进行复制)'],
                       max_col_width=500,
                       auto_size_columns=True,  # 自动调整列宽(根据上面第一次的values默认值为准,update时不会调整)
                       justification='center',  # 字符排列 left right center
                       key='_table_',
                       font=('微软雅黑', 10),
                       text_color='black',
                       background_color='white',
                       enable_events=True,
                       enable_click_events=True,
                       bind_return_key=True,
                       tooltip='This is a table')],
                   ]
    window = sg.Window('网盘资源详情', info_layout, keep_on_top=True, finalize=True, icon=serach)
    return window

界面功能展示

输入关键字点击按钮搜索资源

在这里插入图片描述
在这里插入图片描述

得到资源列表

在这里插入图片描述

左键单击行拿到会帮你把URL复制到粘贴板上

在这里插入图片描述
接下来你就可以把url复制到浏览器上拿到网盘资源啦~~~~~~


3. 注意

  • 其中header的X-Authorization这个参数是需要你自己去抓包拿到的,因为它是jwt验证有过期性,因此你需要定时去更换cookie,本来是想直接过验证的但是它是微信登录验证就不能代码过验证了。
  • 有空的话我再写一下接口是如何找到并且代码是如何调度的
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值