Appearance
使用示例
本页面提供了 NFD Parser 的详细使用示例和代码演示。
在线演示
在学习编程示例之前,先试试我们的在线演示工具:
快速开始
基本解析示例
bash
# 解析蓝奏云分享链接
curl "http://your_host:6400/json/lz/ia2cntg"
# 解析带密码的分享链接
curl "http://your_host:6400/json/fc/e5079007dc31226096628870c7@QAIU"
# 使用通用接口
curl "http://your_host:6400/json/parser?url=https://lanzoux.com/ia2cntg"
编程语言示例
JavaScript / Node.js
基础封装类
javascript
class NFDParser {
constructor(baseUrl = 'http://localhost:6400') {
this.baseUrl = baseUrl;
}
/**
* 解析分享链接
* @param {string} shareUrl - 分享链接
* @param {string} password - 分享密码(可选)
* @returns {Promise<Object>} 解析结果
*/
async parseLink(shareUrl, password = '') {
const params = new URLSearchParams({ url: shareUrl });
if (password) {
params.append('pwd', password);
}
try {
const response = await fetch(`${this.baseUrl}/json/parser?${params}`);
const result = await response.json();
if (result.success) {
return result.data;
} else {
throw new Error(result.msg);
}
} catch (error) {
console.error('解析失败:', error);
throw error;
}
}
/**
* 获取直链(自动跳转)
* @param {string} shareUrl - 分享链接
* @param {string} password - 分享密码(可选)
* @returns {string} 重定向URL
*/
getDirectUrl(shareUrl, password = '') {
const params = new URLSearchParams({ url: shareUrl });
if (password) {
params.append('pwd', password);
}
return `${this.baseUrl}/parser?${params}`;
}
/**
* 获取文件夹列表
* @param {string} shareUrl - 文件夹分享链接
* @param {string} password - 分享密码(可选)
* @returns {Promise<Array>} 文件列表
*/
async getFileList(shareUrl, password = '') {
const params = new URLSearchParams({ url: shareUrl });
if (password) {
params.append('pwd', password);
}
const response = await fetch(`${this.baseUrl}/v2/getFileList?${params}`);
const result = await response.json();
if (result.success) {
return result.data;
} else {
throw new Error(result.msg);
}
}
/**
* 获取统计信息
* @returns {Promise<Object>} 统计数据
*/
async getStatistics() {
const response = await fetch(`${this.baseUrl}/v2/statisticsInfo`);
const result = await response.json();
if (result.success) {
return result.data;
} else {
throw new Error(result.msg);
}
}
}
// 使用示例
const parser = new NFDParser('http://localhost:6400');
// 解析单个文件
parser.parseLink('https://lanzoux.com/ia2cntg')
.then(data => {
console.log('直链:', data.directLink);
console.log('缓存命中:', data.cacheHit);
console.log('过期时间:', data.expires);
})
.catch(error => {
console.error('解析失败:', error.message);
});
// 解析文件夹
parser.getFileList('https://lanzoux.com/folder_link')
.then(files => {
files.forEach(file => {
console.log(`文件: ${file.fileName}, 大小: ${file.sizeStr}`);
});
})
.catch(error => {
console.error('获取文件列表失败:', error.message);
});
Express.js 中间件示例
javascript
const express = require('express');
const app = express();
// NFD Parser 中间件
async function parseNetdiskMiddleware(req, res, next) {
const { url, password } = req.query;
if (!url) {
return res.status(400).json({ error: '缺少分享链接参数' });
}
try {
const parser = new NFDParser();
const result = await parser.parseLink(url, password);
req.parsedResult = result;
next();
} catch (error) {
res.status(500).json({ error: error.message });
}
}
// 使用中间件
app.get('/parse', parseNetdiskMiddleware, (req, res) => {
res.json({
success: true,
data: req.parsedResult
});
});
app.listen(3000, () => {
console.log('服务启动在端口 3000');
});
Python
基础封装类
python
import requests
from urllib.parse import urlencode
from typing import Optional, Dict, List, Any
class NFDParser:
def __init__(self, base_url: str = 'http://localhost:6400'):
self.base_url = base_url
self.session = requests.Session()
def parse_link(self, share_url: str, password: str = '') -> Dict[str, Any]:
"""
解析分享链接
Args:
share_url: 分享链接
password: 分享密码(可选)
Returns:
解析结果字典
"""
params = {'url': share_url}
if password:
params['pwd'] = password
try:
response = self.session.get(
f'{self.base_url}/json/parser',
params=params,
timeout=30
)
response.raise_for_status()
result = response.json()
if result.get('success'):
return result['data']
else:
raise Exception(result.get('msg', '解析失败'))
except requests.RequestException as e:
raise Exception(f'请求失败: {str(e)}')
def get_direct_url(self, share_url: str, password: str = '') -> str:
"""
获取直链(重定向URL)
Args:
share_url: 分享链接
password: 分享密码(可选)
Returns:
重定向URL
"""
params = {'url': share_url}
if password:
params['pwd'] = password
return f"{self.base_url}/parser?{urlencode(params)}"
def get_file_list(self, share_url: str, password: str = '') -> List[Dict[str, Any]]:
"""
获取文件夹列表
Args:
share_url: 文件夹分享链接
password: 分享密码(可选)
Returns:
文件列表
"""
params = {'url': share_url}
if password:
params['pwd'] = password
response = self.session.get(
f'{self.base_url}/v2/getFileList',
params=params,
timeout=30
)
response.raise_for_status()
result = response.json()
if result.get('success'):
return result['data']
else:
raise Exception(result.get('msg', '获取文件列表失败'))
def get_statistics(self) -> Dict[str, Any]:
"""获取统计信息"""
response = self.session.get(f'{self.base_url}/v2/statisticsInfo')
response.raise_for_status()
result = response.json()
if result.get('success'):
return result['data']
else:
raise Exception(result.get('msg', '获取统计信息失败'))
# 使用示例
if __name__ == '__main__':
parser = NFDParser('http://localhost:6400')
try:
# 解析单个文件
result = parser.parse_link('https://lanzoux.com/ia2cntg')
print(f"直链: {result['directLink']}")
print(f"缓存命中: {result['cacheHit']}")
print(f"过期时间: {result['expires']}")
# 获取统计信息
stats = parser.get_statistics()
print(f"解析总数: {stats['parserTotal']}")
print(f"缓存总数: {stats['cacheTotal']}")
except Exception as e:
print(f"错误: {e}")
Django 视图示例
python
from django.http import JsonResponse
from django.views.decorators.http import require_http_methods
from django.views.decorators.csrf import csrf_exempt
import json
@csrf_exempt
@require_http_methods(["POST"])
def parse_netdisk_view(request):
try:
data = json.loads(request.body)
share_url = data.get('url')
password = data.get('password', '')
if not share_url:
return JsonResponse({
'success': False,
'error': '缺少分享链接参数'
}, status=400)
parser = NFDParser()
result = parser.parse_link(share_url, password)
return JsonResponse({
'success': True,
'data': result
})
except Exception as e:
return JsonResponse({
'success': False,
'error': str(e)
}, status=500)
PHP
php
<?php
class NFDParser {
private $baseUrl;
public function __construct($baseUrl = 'http://localhost:6400') {
$this->baseUrl = rtrim($baseUrl, '/');
}
/**
* 解析分享链接
*/
public function parseLink($shareUrl, $password = '') {
$params = ['url' => $shareUrl];
if (!empty($password)) {
$params['pwd'] = $password;
}
$url = $this->baseUrl . '/json/parser?' . http_build_query($params);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode !== 200) {
throw new Exception("HTTP请求失败: $httpCode");
}
$result = json_decode($response, true);
if ($result['success']) {
return $result['data'];
} else {
throw new Exception($result['msg'] ?? '解析失败');
}
}
/**
* 获取直链URL
*/
public function getDirectUrl($shareUrl, $password = '') {
$params = ['url' => $shareUrl];
if (!empty($password)) {
$params['pwd'] = $password;
}
return $this->baseUrl . '/parser?' . http_build_query($params);
}
/**
* 获取文件列表
*/
public function getFileList($shareUrl, $password = '') {
$params = ['url' => $shareUrl];
if (!empty($password)) {
$params['pwd'] = $password;
}
$url = $this->baseUrl . '/v2/getFileList?' . http_build_query($params);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
if ($result['success']) {
return $result['data'];
} else {
throw new Exception($result['msg'] ?? '获取文件列表失败');
}
}
}
// 使用示例
try {
$parser = new NFDParser('http://localhost:6400');
// 解析链接
$result = $parser->parseLink('https://lanzoux.com/ia2cntg');
echo "直链: " . $result['directLink'] . "\n";
echo "缓存命中: " . ($result['cacheHit'] ? '是' : '否') . "\n";
} catch (Exception $e) {
echo "错误: " . $e->getMessage() . "\n";
}
?>
Java
java
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
import java.util.Map;
import java.util.HashMap;
public class NFDParser {
private final String baseUrl;
private final HttpClient httpClient;
private final ObjectMapper objectMapper;
public NFDParser(String baseUrl) {
this.baseUrl = baseUrl.endsWith("/") ? baseUrl.substring(0, baseUrl.length() - 1) : baseUrl;
this.httpClient = HttpClient.newHttpClient();
this.objectMapper = new ObjectMapper();
}
public NFDParser() {
this("http://localhost:6400");
}
/**
* 解析分享链接
*/
public Map<String, Object> parseLink(String shareUrl, String password) throws Exception {
StringBuilder urlBuilder = new StringBuilder(baseUrl + "/json/parser?url=" + shareUrl);
if (password != null && !password.isEmpty()) {
urlBuilder.append("&pwd=").append(password);
}
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(urlBuilder.toString()))
.GET()
.build();
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != 200) {
throw new RuntimeException("HTTP请求失败: " + response.statusCode());
}
Map<String, Object> result = objectMapper.readValue(response.body(), Map.class);
Boolean success = (Boolean) result.get("success");
if (success) {
return (Map<String, Object>) result.get("data");
} else {
throw new RuntimeException((String) result.get("msg"));
}
}
/**
* 获取直链URL
*/
public String getDirectUrl(String shareUrl, String password) {
StringBuilder urlBuilder = new StringBuilder(baseUrl + "/parser?url=" + shareUrl);
if (password != null && !password.isEmpty()) {
urlBuilder.append("&pwd=").append(password);
}
return urlBuilder.toString();
}
// 使用示例
public static void main(String[] args) {
try {
NFDParser parser = new NFDParser("http://localhost:6400");
Map<String, Object> result = parser.parseLink("https://lanzoux.com/ia2cntg", "");
System.out.println("直链: " + result.get("directLink"));
System.out.println("缓存命中: " + result.get("cacheHit"));
System.out.println("过期时间: " + result.get("expires"));
} catch (Exception e) {
System.err.println("错误: " + e.getMessage());
}
}
}
前端集成示例
React 组件
jsx
import React, { useState } from 'react';
import axios from 'axios';
const NetdiskParser = () => {
const [shareUrl, setShareUrl] = useState('');
const [password, setPassword] = useState('');
const [result, setResult] = useState(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState('');
const parseLink = async () => {
if (!shareUrl.trim()) {
setError('请输入分享链接');
return;
}
setLoading(true);
setError('');
setResult(null);
try {
const response = await axios.get('/api/parse', {
params: {
url: shareUrl,
pwd: password
}
});
setResult(response.data.data);
} catch (err) {
setError(err.response?.data?.msg || '解析失败');
} finally {
setLoading(false);
}
};
return (
<div className="netdisk-parser">
<h2>网盘链接解析</h2>
<div className="form-group">
<input
type="text"
placeholder="请输入分享链接"
value={shareUrl}
onChange={(e) => setShareUrl(e.target.value)}
className="form-control"
/>
</div>
<div className="form-group">
<input
type="text"
placeholder="分享密码(可选)"
value={password}
onChange={(e) => setPassword(e.target.value)}
className="form-control"
/>
</div>
<button
onClick={parseLink}
disabled={loading}
className="btn btn-primary"
>
{loading ? '解析中...' : '解析链接'}
</button>
{error && (
<div className="alert alert-danger">
{error}
</div>
)}
{result && (
<div className="result">
<h3>解析结果</h3>
<p><strong>直链:</strong>
<a href={result.directLink} target="_blank" rel="noopener noreferrer">
{result.directLink}
</a>
</p>
<p><strong>缓存命中:</strong> {result.cacheHit ? '是' : '否'}</p>
<p><strong>过期时间:</strong> {result.expires}</p>
</div>
)}
</div>
);
};
export default NetdiskParser;
Vue.js 组件
vue
<template>
<div class="netdisk-parser">
<h2>网盘链接解析</h2>
<el-form @submit.prevent="parseLink">
<el-form-item>
<el-input
v-model="shareUrl"
placeholder="请输入分享链接"
clearable
/>
</el-form-item>
<el-form-item>
<el-input
v-model="password"
placeholder="分享密码(可选)"
clearable
/>
</el-form-item>
<el-form-item>
<el-button
type="primary"
:loading="loading"
@click="parseLink"
>
解析链接
</el-button>
</el-form-item>
</el-form>
<el-alert
v-if="error"
:title="error"
type="error"
:closable="false"
/>
<el-card v-if="result" class="result-card">
<h3>解析结果</h3>
<p><strong>直链:</strong>
<a :href="result.directLink" target="_blank">
{{ result.directLink }}
</a>
</p>
<p><strong>缓存命中:</strong> {{ result.cacheHit ? '是' : '否' }}</p>
<p><strong>过期时间:</strong> {{ result.expires }}</p>
</el-card>
</div>
</template>
<script>
import axios from 'axios';
export default {
name: 'NetdiskParser',
data() {
return {
shareUrl: '',
password: '',
result: null,
loading: false,
error: ''
};
},
methods: {
async parseLink() {
if (!this.shareUrl.trim()) {
this.error = '请输入分享链接';
return;
}
this.loading = true;
this.error = '';
this.result = null;
try {
const response = await axios.get('/api/parse', {
params: {
url: this.shareUrl,
pwd: this.password
}
});
this.result = response.data.data;
} catch (err) {
this.error = err.response?.data?.msg || '解析失败';
} finally {
this.loading = false;
}
}
}
};
</script>
命令行工具示例
Bash 脚本
bash
#!/bin/bash
# NFD Parser 命令行工具
NFD_HOST="http://localhost:6400"
usage() {
echo "用法: $0 [选项] <分享链接>"
echo "选项:"
echo " -p, --password <密码> 分享密码"
echo " -h, --help 显示此帮助信息"
echo " -j, --json 输出JSON格式"
echo " -s, --stats 显示统计信息"
echo ""
echo "示例:"
echo " $0 https://lanzoux.com/ia2cntg"
echo " $0 -p QAIU https://v2.fangcloud.com/sharing/xxx"
echo " $0 -j https://lanzoux.com/ia2cntg"
echo " $0 -s"
}
parse_link() {
local url="$1"
local password="$2"
local json_output="$3"
if [ -z "$url" ]; then
echo "错误: 缺少分享链接"
exit 1
fi
local api_url="${NFD_HOST}/json/parser?url=$(urlencode "$url")"
if [ -n "$password" ]; then
api_url="${api_url}&pwd=$(urlencode "$password")"
fi
local response=$(curl -s "$api_url")
local success=$(echo "$response" | jq -r '.success')
if [ "$success" = "true" ]; then
if [ "$json_output" = "true" ]; then
echo "$response"
else
local direct_link=$(echo "$response" | jq -r '.data.directLink')
local cache_hit=$(echo "$response" | jq -r '.data.cacheHit')
local expires=$(echo "$response" | jq -r '.data.expires')
echo "解析成功!"
echo "直链: $direct_link"
echo "缓存命中: $cache_hit"
echo "过期时间: $expires"
fi
else
local msg=$(echo "$response" | jq -r '.msg')
echo "解析失败: $msg"
exit 1
fi
}
show_stats() {
local response=$(curl -s "${NFD_HOST}/v2/statisticsInfo")
local success=$(echo "$response" | jq -r '.success')
if [ "$success" = "true" ]; then
local parser_total=$(echo "$response" | jq -r '.data.parserTotal')
local cache_total=$(echo "$response" | jq -r '.data.cacheTotal')
local total=$(echo "$response" | jq -r '.data.total')
echo "解析统计信息:"
echo "解析总数: $parser_total"
echo "缓存总数: $cache_total"
echo "总计: $total"
else
echo "获取统计信息失败"
exit 1
fi
}
urlencode() {
echo "$1" | sed 's/:/%3A/g; s/\//%2F/g; s/?/%3F/g; s/#/%23/g; s/\[/%5B/g; s/\]/%5D/g; s/@/%40/g; s/!/%21/g; s/\$/%24/g; s/&/%26/g; s/'\''/%27/g; s/(/%28/g; s/)/%29/g; s/\*/%2A/g; s/+/%2B/g; s/,/%2C/g; s/;/%3B/g; s/=/%3D/g; s/ /%20/g'
}
# 解析命令行参数
password=""
json_output=false
show_statistics=false
while [[ $# -gt 0 ]]; do
case $1 in
-p|--password)
password="$2"
shift 2
;;
-j|--json)
json_output=true
shift
;;
-s|--stats)
show_statistics=true
shift
;;
-h|--help)
usage
exit 0
;;
*)
share_url="$1"
shift
;;
esac
done
# 执行相应操作
if [ "$show_statistics" = "true" ]; then
show_stats
else
parse_link "$share_url" "$password" "$json_output"
fi
批量处理示例
Python 批量解析脚本
python
import csv
import time
from concurrent.futures import ThreadPoolExecutor, as_completed
from nfd_parser import NFDParser # 假设上面的类保存为 nfd_parser.py
def parse_single_link(parser, link_data):
"""解析单个链接"""
try:
result = parser.parse_link(link_data['url'], link_data.get('password', ''))
return {
'original_url': link_data['url'],
'direct_link': result['directLink'],
'cache_hit': result['cacheHit'],
'expires': result['expires'],
'status': 'success',
'error': None
}
except Exception as e:
return {
'original_url': link_data['url'],
'direct_link': None,
'cache_hit': None,
'expires': None,
'status': 'error',
'error': str(e)
}
def batch_parse_links(input_file, output_file, max_workers=5):
"""批量解析链接"""
parser = NFDParser()
links = []
# 读取输入文件
with open(input_file, 'r', encoding='utf-8') as f:
reader = csv.DictReader(f)
links = list(reader)
print(f"准备解析 {len(links)} 个链接...")
results = []
with ThreadPoolExecutor(max_workers=max_workers) as executor:
# 提交任务
future_to_link = {
executor.submit(parse_single_link, parser, link): link
for link in links
}
# 收集结果
for future in as_completed(future_to_link):
result = future.result()
results.append(result)
status = "✓" if result['status'] == 'success' else "✗"
print(f"{status} {result['original_url']}")
# 避免请求过于频繁
time.sleep(0.1)
# 写入结果文件
with open(output_file, 'w', encoding='utf-8', newline='') as f:
fieldnames = ['original_url', 'direct_link', 'cache_hit', 'expires', 'status', 'error']
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(results)
# 统计结果
success_count = sum(1 for r in results if r['status'] == 'success')
error_count = len(results) - success_count
print(f"\n解析完成!")
print(f"成功: {success_count}")
print(f"失败: {error_count}")
print(f"结果已保存到: {output_file}")
if __name__ == '__main__':
# 输入文件格式: url,password
batch_parse_links('input_links.csv', 'output_results.csv')
错误处理和重试机制
JavaScript 重试示例
javascript
class NFDParserWithRetry extends NFDParser {
constructor(baseUrl, options = {}) {
super(baseUrl);
this.maxRetries = options.maxRetries || 3;
this.retryDelay = options.retryDelay || 1000;
}
async parseWithRetry(shareUrl, password = '') {
let lastError;
for (let attempt = 1; attempt <= this.maxRetries; attempt++) {
try {
return await this.parseLink(shareUrl, password);
} catch (error) {
lastError = error;
console.warn(`解析失败 (尝试 ${attempt}/${this.maxRetries}): ${error.message}`);
if (attempt < this.maxRetries) {
await this.delay(this.retryDelay * attempt);
}
}
}
throw lastError;
}
delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
}
// 使用示例
const parser = new NFDParserWithRetry('http://localhost:6400', {
maxRetries: 3,
retryDelay: 2000
});
parser.parseWithRetry('https://lanzoux.com/ia2cntg')
.then(result => console.log('解析成功:', result))
.catch(error => console.error('最终失败:', error));
这些示例展示了如何在不同编程语言和场景中使用 NFD Parser API。您可以根据具体需求选择合适的示例进行修改和使用。