夸克网盘自动转存分享

import logging
import random
import re
import time

import requests

from sqlite import SqlLiteOperator

logging.getLogger().setLevel(logging.INFO)


def get_id_from_url(url) -> str:
    """pwd_id"""
    pattern = r"/s/(\w+)"
    match = re.search(pattern, url)
    if match:
        return match.group(1)
    return ""


def generate_timestamp(length):
    timestamps = str(time.time() * 1000)
    return int(timestamps[0:length])


class Quark:
    ad_pwd_id = "cea9ecf48a914a07b4e28ba499af820f"

    def __init__(self, cookie: str) -> None:
        self.headers = {
            'sec-ch-ua': '"Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"',
            'accept': 'application/json, text/plain, */*',
            'content-type': 'application/json',
            'sec-ch-ua-mobile': '?0',
            'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
            'sec-ch-ua-platform': '"Windows"',
            'origin': 'https://pan.quark.cn',
            'sec-fetch-site': 'same-site',
            'sec-fetch-mode': 'cors',
            'sec-fetch-dest': 'empty',
            'referer': 'https://pan.quark.cn/',
            'accept-encoding': 'gzip, deflate, br',
            'accept-language': 'zh-CN,zh;q=0.9',
            'cookie': cookie}

        self.operator = SqlLiteOperator()
        self.parent_dir = None

    def store(self, url: str):
        pwd_id = get_id_from_url(url)
        stoken = self.get_stoken(pwd_id)
        detail = self.detail(pwd_id, stoken)
        file_name = detail.get('title')

        if self.operator.fetch_files(file_name):
            first_id, share_fid_token, file_type = detail.get("fid"), detail.get("share_fid_token"), detail.get(
                "file_type")

            # 匹配指定的父目录,仅支持根目录下的目录
            other_args = {}
            if self.parent_dir is not None:
                other_args['to_pdir_fid'] = self.parent_dir

            task = self.save_task_id(pwd_id, stoken, first_id, share_fid_token, **other_args)
            data = self.task(task)
            file_id = data.get("data").get("save_as").get("save_as_top_fids")[0]
            if not file_type:
                dir_file_list = self.get_dir_file(file_id)
                self.del_ad_file(dir_file_list)
            share_task_id = self.share_task_id(file_id, file_name)
            share_id = self.task(share_task_id).get("data").get("share_id")
            share_link = self.get_share_link(share_id)
            self.operator.insert_files(file_id, file_name, file_type, share_link)

    def get_stoken(self, pwd_id: str):
        url = f"https://drive-pc.quark.cn/1/clouddrive/share/sharepage/token?pr=ucpro&fr=pc&uc_param_str=&__dt=405&__t={generate_timestamp(13)}"
        payload = {"pwd_id": pwd_id, "passcode": ""}
        headers = self.headers
        response = requests.post(url, json=payload, headers=headers).json()
        if response.get("data"):
            return response["data"]["stoken"]
        else:
            return ""

    def detail(self, pwd_id, stoken):
        url = f"https://drive-pc.quark.cn/1/clouddrive/share/sharepage/detail"
        headers = self.headers
        params = {
            "pwd_id": pwd_id,
            "stoken": stoken,
            "pdir_fid": 0,
            "_page": 1,
            "_size": "50",
        }
        response = requests.request("GET", url=url, headers=headers, params=params)
        id_list = response.json().get("data").get("list")[0]
        if id_list:
            data = {
                "title": id_list.get("file_name"),
                "file_type": id_list.get("file_type"),
                "fid": id_list.get("fid"),
                "pdir_fid": id_list.get("pdir_fid"),
                "share_fid_token": id_list.get("share_fid_token")
            }
            return data

    def save_task_id(self, pwd_id, stoken, first_id, share_fid_token, to_pdir_fid=0):
        """
        pwd_id: 资源目录
        stoken: stoken
        """
        logging.info("获取保存文件的TASKID")
        url = "https://drive.quark.cn/1/clouddrive/share/sharepage/save"
        params = {
            "pr": "ucpro",
            "fr": "pc",
            "uc_param_str": "",
            "__dt": int(random.uniform(1, 5) * 60 * 1000),
            "__t": generate_timestamp(13),
        }
        data = {"fid_list": [first_id],
                "fid_token_list": [share_fid_token],
                "to_pdir_fid": to_pdir_fid, "pwd_id": pwd_id,
                "stoken": stoken, "pdir_fid": "0", "scene": "link"}
        response = requests.request("POST", url, json=data, headers=self.headers, params=params)
        logging.info(response.json())
        task_id = response.json().get('data').get('task_id')
        return task_id

    def set_store_dir(self, name_or_id):
        """
        :param name_or_id: 存储的文件夹名称或者id,只支持根目录下的目录
        :return:
        """
        logging.info("设置存储目录")
        files = self.get_all_file()
        pdir_id = [x for x in files if x['file_name'] == name_or_id or x['fid'] == name_or_id]
        if pdir_id:
            self.parent_dir = pdir_id[0]['fid']
        else:
            raise ValueError("文件夹不存在")

    def task(self, task_id):
        """根据task_id进行任务"""
        logging.info("根据TASKID执行任务")
        while True:
            url = f"https://drive-pc.quark.cn/1/clouddrive/task?pr=ucpro&fr=pc&uc_param_str=&task_id={task_id}&retry_index={range}&__dt=21192&__t={generate_timestamp(13)}"
            response = requests.get(url, headers=self.headers).json()
            logging.info(response)
            if response.get('data').get('status') == 2:
                return response

    def share_task_id(self, file_id, file_name):
        """创建分享任务ID"""
        url = "https://drive-pc.quark.cn/1/clouddrive/share?pr=ucpro&fr=pc&uc_param_str="
        data = {"fid_list": [file_id],
                "title": file_name,
                "url_type": 1, "expired_type": 1}
        response = requests.request("POST", url=url, json=data, headers=self.headers)
        return response.json().get("data").get("task_id")

    def get_share_link(self, share_id):
        url = "https://drive-pc.quark.cn/1/clouddrive/share/password?pr=ucpro&fr=pc&uc_param_str="
        data = {"share_id": share_id}
        response = requests.post(url=url, json=data, headers=self.headers)
        return response.json().get("data").get("share_url")

    def get_all_file(self):
        """获取所有文件id"""
        logging.info("正在获取所有文件")
        url = "https://drive-pc.quark.cn/1/clouddrive/file/sort?pr=ucpro&fr=pc&uc_param_str=&pdir_fid=0&_page=1&_size=50&_fetch_total=1&_fetch_sub_dirs=0&_sort=file_type:asc,updated_at:desc"
        response = requests.get(url, headers=self.headers)
        file_list = response.json().get('data').get('list')
        return file_list

    def get_dir_file(self, dir_id) -> list:
        logging.info("正在遍历父文件夹")
        """获取指定文件夹的文件,后期可能会递归"""
        url = f"https://drive-pc.quark.cn/1/clouddrive/file/sort?pr=ucpro&fr=pc&uc_param_str=&pdir_fid={dir_id}&_page=1&_size=50&_fetch_total=1&_fetch_sub_dirs=0&_sort=updated_at:desc"
        response = requests.get(url=url, headers=self.headers)
        files_list = response.json().get('data').get('list')
        return files_list

    def del_file(self, file_id):
        logging.info("正在删除文件")
        url = "https://drive-pc.quark.cn/1/clouddrive/file/delete?pr=ucpro&fr=pc&uc_param_str="
        data = {"action_type": 2, "filelist": [file_id], "exclude_fids": []}
        response = requests.post(url=url, json=data, headers=self.headers)
        if response.status_code == 200:
            return response.json().get("data").get("task_id")
        return False

    def del_ad_file(self, file_list):
        logging.info("删除可能存在广告的文件")
        for file in file_list:
            file_name = file.get("file_name")
            from ad_check import ad_check
            if ad_check(file_name):
                task_id = self.del_file(file.get("fid"))
                self.task(task_id)

    def search_file(self, file_name):
        logging.info("正在从网盘搜索文件🔍")
        url = "https://drive-pc.quark.cn/1/clouddrive/file/search?pr=ucpro&fr=pc&uc_param_str=&_page=1&_size=50&_fetch_total=1&_sort=file_type:desc,updated_at:desc&_is_hl=1"
        params = {"q": file_name}
        response = requests.get(url=url, headers=self.headers, params=params)
        return response.json().get('data').get('list')


if __name__ == '__main__':
    cookie = ''
    quark = Quark(cookie)
    quark.store('https://pan.quark.cn/s/0dcedfa1c18f#/list/share')

明天更新相应代码,使其自动处理数据,完成转存分享整理上传

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值