如何基于提供的代码实现兼容Python2/3的MediaFire文件夹文件直链获取功能
如何基于提供的代码实现兼容Python2/3的MediaFire文件夹文件直链获取功能
嘿,如果你想搞一个能同时在Python2和Python3环境下运行的MediaFire文件夹文件直链获取功能,咱们可以结合代码片段一步步实现,过程其实挺清晰的,一起来看看吧。
一、先搭建Python2/3兼容层
首先得搞定版本兼容的问题,因为Python2和3在网络请求、字符串处理这些地方差异不小,咱们先写一个compat.py模块,把这些差异抹平,后面写核心逻辑的时候就不用反复判断版本了:
from sys import version_info from threading import Thread PY3 = version_info[0] == 3 # Disable certificate verification on python 2.7.9 if version_info >= (2, 7, 9): import ssl ssl._create_default_https_context = ssl._create_unverified_context if version_info[0] == 2: # Python 2 compat_str, compat_basestring, compat_chr = (unicode, basestring, unichr) compat_integer_types = (int, long) compat_numeric_types = (int, float, long, complex) from re import compile from urllib import _hextochr from itertools import izip_longest as compat_zip_longest from urllib import urlencode as compat_urlencode from urllib import quote as compat_quote from urllib import urlretrieve as compat_urlretrieve from urllib2 import urlopen from urllib2 import Request as compat_Request from urllib2 import HTTPError as compat_HTTPError from urllib2 import URLError as compat_URLError from urlparse import urljoin as compat_urljoin from urlparse import urlparse as compat_urlparse from urlparse import urlunparse as compat_urlunparse from httplib import HTTPException as compat_HTTPException def _unquote_to_bytes(string): if not string: return b'' if isinstance(string, unicode): string = string.encode('utf-8') bits = string.split(b'%') if len(bits) == 1: return string res = [bits[0]] for item in bits[1:]: try: res.append(_hextochr[item[:2]]) res.append(item[2:]) except KeyError: res.append(b'%') res.append(item) return b''.join(res) def _unquote(string): if '%' not in string: return string bits = compile(r'([\x00-\x7f]+)').split(string) res = [bits[0]] for i in range(1, len(bits), 2): res.append(_unquote_to_bytes(bits[i]).decode('utf-8', 'replace')) res.append(bits[i + 1]) return ''.join(res) def _parse_qsl(qs): pairs = [s2 for s1 in qs.split('&') for s2 in s1.split(';')] r = [] for name_value in pairs: if not name_value: continue nv = name_value.split('=', 1) if len(nv) == 2 and len(nv[1]): name = unicode(_unquote(nv[0].replace('+', ' '))) value = unicode(_unquote(nv[1].replace('+', ' '))) r.append((name, value)) return r def compat_parse_qs(qs): """ Correct parse_qs implementation from cpython 3's stdlib. Python 2's version is apparently totally broken. """ parsed_result = {} pairs = _parse_qsl(qs) for name, value in pairs: if name in parsed_result: parsed_result[name].append(value) else: parsed_result[name] = [value] return parsed_result else: # Python 3 compat_str, compat_basestring, compat_chr = (str, (str, bytes), chr) compat_integer_types = (int, ) compat_numeric_types = (int, float, complex) from itertools import zip_longest as compat_zip_longest from urllib.parse import urlencode as compat_urlencode from urllib.parse import quote as compat_quote from urllib.request import urlretrieve as compat_urlretrieve from urllib.request import urlopen from urllib.request import Request as compat_Request from urllib.error import HTTPError as compat_HTTPError from urllib.error import URLError as compat_URLError from urllib.parse import urljoin as compat_urljoin from urllib.parse import urlparse as compat_urlparse from urllib.parse import parse_qs as compat_parse_qs from urllib.parse import urlunparse as compat_urlunparse from http.client import HTTPException as compat_HTTPException if version_info >= (3, 4): from collections import ChainMap as compat_chain_map else: from collections import MutableMapping class compat_chain_map(MutableMapping): def __init__(self, *maps): self.maps = list(maps) or [{}] def __getitem__(self, k): for m in self.maps: if k in m: return m[k] raise KeyError(k) def __contains__(self, k): return any((k in m) for m in self.maps) def __delitem__(self, k): raise NotImplementedError('Deleting is not supported') def __iter__(self): d = {} for m in reversed(self.maps): d.update(m) return iter(d) def __len__(self): d = {} for m in reversed(self.maps): d.update(m) return len(d)
二、编写MediaFire文件直链获取的核心代码
接下来就是核心功能了:根据指定的团队名和设备类型,匹配对应的MediaFire文件夹Key,调用官方API获取文件列表,最后提取出文件名和直链。
首先,咱们需要实现get_images_mediafire函数,用来解析MediaFire API返回的JSON数据:
import json from compat import urlopen, compat_HTTPError, compat_URLError def get_images_mediafire(api_url): """解析MediaFire文件夹API返回,提取文件名和下载直链""" try: response = urlopen(api_url) # 处理编码,兼容Python2/3 content = response.read().decode('utf-8') data = json.loads(content) if data.get('response', {}).get('result') != 'Success': return [] files = data.get('response', {}).get('folder_content', {}).get('files', []) result = [] for file_info in files: file_name = file_info.get('filename') # 获取直接下载链接 file_link = file_info.get('links', {}).get('normal_download') if file_name and file_link: result.append((file_name, file_link)) return result except (compat_HTTPError, compat_URLError, json.JSONDecodeError) as e: print(f"获取MediaFire文件列表出错: {e}") return []
然后是主逻辑部分,用来匹配文件夹Key并调用上面的函数:
def get_mediafire_files(team_name, box_type): """根据团队名和设备类型获取MediaFire文件夹内的文件列表""" images = [] if team_name == "BlackHole": # 根据设备类型匹配对应的MediaFire文件夹Key folder_keys = { "dm920": "cdmen9tqtpwxk", "dm520": "gkhsdcxiikosk", "dm7080": "5cmni3i0rch9e", "dm820": "60ptu82mgakx6" } key = folder_keys.get(box_type) if not key: return [] # 拼接MediaFire API请求地址 images_path = 'https://www.mediafire.com/api/1.4/folder/get_content.php?r=cfgd&content_type=files&filter=all&order_by=name&order_direction=asc&chunk=1&version=1.5&folder_key=%s&response_format=json' % key rimages = get_images_mediafire(images_path) for item in rimages: image_name, image_path = item images.append((image_name, image_path)) return images
三、测试使用
现在你可以直接调用get_mediafire_files函数来获取文件列表了,比如:
# 测试获取BlackHole团队下dm920设备对应的MediaFire文件夹文件 files = get_mediafire_files("BlackHole", "dm920") if files: print("获取到的文件列表:") for name, link in files: print(f"文件名: {name},下载链接: {link}") else: print("未获取到任何文件或参数不匹配")
这样就能在Python2和Python3环境下都正常运行,拿到MediaFire文件夹里的文件直链啦。
内容来源于stack exchange
相关产品推荐
相关产品推荐

