标题: 发一个稻壳巴巴下载器源码
时间: 11小时前发布,11小时前修改
<?php
/**
* 稻壳阅读器辅助工具 - 单文件PHP版
* 道客巴巴文档下载链接生成器
*
* 内置Token: cc60gZ3OkRfwIVyDdiZ-NBoXhoL9YtYc49sv0VrpSZfci5IX1LRK0bPdp4_a5kMxYVF6xW8u0g61m3Nj5oXHw99mgWaOChi4HiaPfPHJmbwbyqJ8Lu8xBON8Uca4EIHNIeGVsScnUkHVjU7QXiE
*/
// ==================== 配置 ====================
error_reporting(0);
session_start();
header('Content-Type: text/html; charset=utf-8');
// 内置Token
define('DEFAULT_TOKEN', 'cc60gZ3OkRfwIVyDdiZ-NBoXhoL9YtYc49sv0VrpSZfci5IX1LRK0bPdp4_a5kMxYVF6xW8u0g61m3Nj5oXHw99mgWaOChi4HiaPfPHJmbwbyqJ8Lu8xBON8Uca4EIHNIeGVsScnUkHVjU7QXiE');
// ==================== API接口 ====================
if (isset($_GET['api'])) {
header('Content-Type: application/json; charset=utf-8');
$docId = $_GET['docId'] ?? '';
$token = $_GET['token'] ?? DEFAULT_TOKEN;
// 提取docId
if (preg_match('/p-(\d+)/', $docId, $matches)) {
$docId = $matches[1];
}
if (empty($docId)) {
echo json_encode(['success' => false, 'error' => '无效的文档ID']);
exit;
}
// 构建API URL
$apiUrl = 'https://www.doc88.com/doc.php?act=xdfdownload&p_code=' . $docId . '&token=' . urlencode($token);
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $apiUrl,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_TIMEOUT => 30,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_HTTPHEADER => [
'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
'Accept: application/json, text/javascript, */*; q=0.01',
'X-Requested-With: XMLHttpRequest',
'Referer: https://www.doc88.com/p-' . $docId . '.html'
]
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$data = json_decode($response, true);
// result=0 表示成功
if ($data && isset($data['result']) && $data['result'] == 0 && !empty($data['doclink'])) {
$doclink = $data['doclink'];
// 解析下载链接
if (preg_match('/dl\.doc88\.com\/download\/([a-f0-9]{16})\/(.+)\.xdf/i', $doclink, $matches)) {
$hash = $matches[1];
$filename = $matches[2] . '.xdf';
$downloadUrl = 'https://dl.doc88.com/download/' . $hash . '/' . $filename;
echo json_encode([
'success' => true,
'docId' => $docId,
'download' => [
'hash' => $hash,
'filename' => $filename,
'url' => $downloadUrl,
'size' => $data['filesize'] ?? ''
]
], JSON_UNESCAPED_UNICODE);
} else {
echo json_encode([
'success' => true,
'docId' => $docId,
'download' => [
'url' => $doclink,
'filename' => basename($doclink),
'raw' => $doclink
]
], JSON_UNESCAPED_UNICODE);
}
} else {
echo json_encode([
'success' => false,
'error' => $data['doclink'] ?? $data['message'] ?? '获取失败',
'docId' => $docId,
'raw' => $data
], JSON_UNESCAPED_UNICODE);
}
exit;
}
// ==================== 直接下载接口 ====================
if (isset($_GET['download'])) {
$docId = $_GET['download'];
$token = $_GET['token'] ?? DEFAULT_TOKEN;
// 提取docId
if (preg_match('/p-(\d+)/', $docId, $matches)) {
$docId = $matches[1];
}
// 调用API获取下载链接
$apiUrl = 'https://www.doc88.com/doc.php?act=xdfdownload&p_code=' . $docId . '&token=' . urlencode($token);
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $apiUrl,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_TIMEOUT => 30,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_HTTPHEADER => [
'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
'Accept: application/json',
'X-Requested-With: XMLHttpRequest',
'Referer: https://www.doc88.com/p-' . $docId . '.html'
]
]);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);
// result=0 表示成功
if ($data && isset($data['result']) && $data['result'] == 0 && !empty($data['doclink'])) {
// 重定向到下载链接
header('Location: ' . $data['doclink']);
exit;
} else {
echo '获取下载链接失败: ' . ($data['doclink'] ?? $data['message'] ?? '未知错误');
exit;
}
}
// ==================== HTML页面 ====================
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>稻壳阅读器辅助工具 - PHP版</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Microsoft YaHei", sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
padding: 20px;
}
.container { max-width: 700px; margin: 0 auto; }
.header { text-align: center; color: white; margin-bottom: 30px; }
.header h1 { font-size: 2em; margin-bottom: 8px; }
.header p { opacity: 0.9; }
.card {
background: white;
border-radius: 20px;
box-shadow: 0 20px 60px rgba(0,0,0,0.3);
padding: 30px;
margin-bottom: 20px;
}
.card h2 { margin-bottom: 15px; color: #333; }
.input-group { margin-bottom: 18px; }
.input-group label {
display: block;
margin-bottom: 6px;
font-weight: 600;
color: #333;
}
.input-group input {
width: 100%;
padding: 14px;
border: 2px solid #e0e0e0;
border-radius: 10px;
font-size: 15px;
font-family: inherit;
transition: border-color 0.3s;
}
.input-group input:focus {
outline: none;
border-color: #667eea;
}
.input-group input::placeholder { color: #999; }
.input-hint { font-size: 12px; color: #666; margin-top: 4px; line-height: 1.6; }
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 6px;
padding: 14px 28px;
border: none;
border-radius: 10px;
font-size: 15px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s;
}
.btn-primary {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
width: 100%;
}
.btn-primary:hover { transform: translateY(-2px); box-shadow: 0 10px 30px rgba(102, 126, 234, 0.4); }
.btn-success {
background: linear-gradient(135deg, #27ae60 0%, #2ecc71 100%);
color: white;
text-decoration: none;
font-size: 18px;
padding: 20px 50px;
}
.btn-success:hover { transform: translateY(-3px); box-shadow: 0 15px 40px rgba(39, 174, 96, 0.4); }
.btn-group { display: flex; gap: 10px; flex-wrap: wrap; }
.result-box { margin-top: 20px; padding: 20px; border-radius: 10px; display: none; }
.result-box.success { background: #d4edda; border: 1px solid #c3e6cb; color: #155724; }
.result-box.error { background: #f8d7da; border: 1px solid #f5c6cb; color: #721c24; }
.result-box.loading { background: #cce5ff; border: 1px solid #b8daff; color: #004085; text-align: center; }
.result-box.show { display: block; }
.download-card {
background: white;
border: 3px solid #27ae60;
border-radius: 15px;
padding: 40px;
text-align: center;
margin: 20px 0;
transition: all 0.3s;
}
.download-card:hover { transform: translateY(-5px); box-shadow: 0 15px 40px rgba(39, 174, 96, 0.3); }
.download-card .icon { font-size: 70px; margin-bottom: 15px; }
.download-card .title { font-size: 24px; font-weight: 600; color: #27ae60; margin-bottom: 10px; }
.download-card .filename { font-size: 16px; color: #666; margin-bottom: 25px; word-break: break-all; padding: 0 20px; }
.doc-info { background: #f8f9fa; border-radius: 8px; padding: 15px; margin-top: 15px; }
.doc-info .row { display: flex; padding: 8px 0; border-bottom: 1px solid #eee; }
.doc-info .row:last-child { border-bottom: none; }
.doc-info .label { width: 80px; font-weight: 600; color: #666; flex-shrink: 0; }
.doc-info .value { flex: 1; color: #333; word-break: break-all; font-size: 14px; }
.info-box { background: #e7f3ff; border-radius: 10px; padding: 15px; margin: 15px 0; }
.info-box h4 { color: #333; margin-bottom: 10px; }
.info-box ol { margin-left: 20px; color: #555; line-height: 1.8; }
.note { background: #fff3cd; border: 1px solid #ffc107; border-radius: 8px; padding: 12px; margin-top: 15px; font-size: 13px; color: #856404; }
.api-debug { background: #2c3e50; color: #ecf0f1; border-radius: 8px; padding: 15px; margin: 10px 0; }
.api-debug pre { font-size: 12px; overflow-x: auto; white-space: pre-wrap; word-break: break-all; }
.spinner {
width: 40px; height: 40px;
border: 4px solid rgba(255,255,255,0.3);
border-top-color: white;
border-radius: 50%;
animation: spin 1s linear infinite;
margin: 0 auto 15px;
}
@keyframes spin { to { transform: rotate(360deg); } }
.sample-btn {
background: #f39c12;
color: white;
border: none;
padding: 8px 16px;
border-radius: 6px;
cursor: pointer;
font-size: 13px;
margin-left: 10px;
}
.sample-btn:hover { background: #e67e22; }
.direct-download {
background: linear-gradient(135deg, #3498db 0%, #2980b9 100%);
color: white;
padding: 12px 24px;
border-radius: 8px;
text-decoration: none;
display: inline-block;
margin-top: 15px;
font-size: 14px;
}
.direct-download:hover { transform: translateY(-2px); box-shadow: 0 8px 25px rgba(52, 152, 219, 0.4); }
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>📥 稻壳阅读器辅助工具</h1>
<p>道客巴巴文档下载链接生成器 · 内置Token</p>
</div>
<div class="card">
<h2>📎 输入文档链接</h2>
<div class="input-group">
<label for="docUrl">道客巴巴文档链接</label>
<div style="display:flex;gap:10px;">
<input type="text" id="docUrl" placeholder="例如: https://www.doc88.com/p-2651690899469.html" style="flex:1;">
<button class="sample-btn" onclick="loadSample()">加载示例</button>
</div>
<div class="input-hint">支持完整链接或纯ID,如: p-2651690899469 或 2651690899469</div>
</div>
<button class="btn btn-primary" onclick="getDownloadLink()">
🔍 获取下载链接
</button>
<div id="resultBox" class="result-box"></div>
</div>
<div class="card">
<div class="info-box">
<h4>💡 使用说明</h4>
<ol>
<li>输入文档链接,点击"获取下载链接"</li>
<li>Token已内置,直接使用</li>
<li>点击"直接下载"按钮下载文件</li>
</ol>
</div>
<div class="note">
<strong>⚠️ 注意:</strong> Token可能有过期时间,如果下载失败可能需要更新Token
</div>
</div>
</div>
<script>
// 示例数据
const samples = [
{ url: 'https://www.doc88.com/p-2651690899469.html', name: '示例文档1' },
{ url: 'https://www.doc88.com/p-9116601893972.html', name: '示例文档2' },
{ url: 'https://www.doc88.com/p-2148414045355.html', name: '示例文档3' }
];
let sampleIndex = 0;
function loadSample() {
const sample = samples[sampleIndex % samples.length];
document.getElementById('docUrl').value = sample.url;
sampleIndex++;
}
function showResult(html, type) {
const box = document.getElementById('resultBox');
box.className = 'result-box ' + type + ' show';
box.innerHTML = html;
}
function showLoading(msg) {
showResult('<div class="spinner"></div><div>' + msg + '</div>', 'loading');
}
async function getDownloadLink() {
const docUrl = document.getElementById('docUrl').value.trim();
let docId = '';
const match = docUrl.match(/doc88\.com\/p-(\d+)/);
if (match) docId = match[1];
else {
const simpleMatch = docUrl.match(/p-(\d+)/);
if (simpleMatch) docId = simpleMatch[1];
else if (/^\d+$/.test(docUrl)) docId = docUrl;
}
if (!docId) {
showResult('请输入有效的文档链接', 'error');
return;
}
showLoading('正在获取下载链接...');
try {
const response = await fetch('?api=get_download&docId=' + encodeURIComponent(docId));
const data = await response.json();
if (data.success && data.download) {
displayDownloadResult(data.download, docId);
} else {
displayError(data, docId);
}
} catch (err) {
showResult('请求失败: ' + err.message, 'error');
}
}
function displayDownloadResult(download, docId) {
const filename = download.filename || 'document_' + docId.slice(-8);
const downloadUrl = download.url || download.raw;
// 生成直接下载链接
const directUrl = '?download=' + docId;
const html = '<div class="download-card">' +
'<div class="icon">✅</div>' +
'<div class="title">下载链接获取成功!</div>' +
'<div class="filename">' + filename + '</div>' +
'<div>' +
'<a href="' + downloadUrl + '" class="btn btn-success" target="_blank" download>📥 直接下载</a>' +
'</div>' +
'<a href="' + directUrl + '" class="direct-download">🔄 代理下载 (备用)</a>' +
'</div>' +
'<div class="doc-info">' +
'<div class="row"><span class="label">文件名</span><span class="value">' + filename + '</span></div>' +
'<div class="row"><span class="label">Hash</span><span class="value">' + (download.hash || 'N/A') + '</span></div>' +
'<div class="row"><span class="label">文档ID</span><span class="value">' + docId + '</span></div>' +
(download.size ? '<div class="row"><span class="label">大小</span><span class="value">' + formatSize(download.size) + '</span></div>' : '') +
'</div>' +
'<div style="margin-top:15px;text-align:center;"><button class="btn btn-secondary" onclick="copyToClipboard(\'' + downloadUrl + '\')">📋 复制下载链接</button></div>';
showResult(html, 'success');
}
function displayError(data, docId) {
const html = '<div style="margin-bottom:15px;"><h3>❌ 获取失败</h3><p>' + (data.error || '未知错误') + '</p></div>' +
'<div class="api-debug"><strong>API响应:</strong><pre>' + JSON.stringify(data, null, 2) + '</pre></div>' +
'<div class="note"><strong>可能原因:</strong> Token过期、文档需VIP权限、或文档不存在</div>';
showResult(html, 'error');
}
function formatSize(bytes) {
if (!bytes) return 'N/A';
const b = parseInt(bytes);
if (b < 1024) return b + ' B';
if (b < 1024 * 1024) return (b / 1024).toFixed(1) + ' KB';
return (b / 1024 / 1024).toFixed(1) + ' MB';
}
function copyToClipboard(text) {
navigator.clipboard.writeText(text).then(() => alert('下载链接已复制!')).catch(() => {
const ta = document.createElement('textarea');
ta.value = text;
document.body.appendChild(ta);
ta.select();
document.execCommand('copy');
document.body.removeChild(ta);
alert('下载链接已复制!');
});
}
document.getElementById('docUrl')?.addEventListener('keypress', e => { if (e.key === 'Enter') getDownloadLink(); });
</script>
</body>
</html>
『回复列表(2|显示机器人聊天)』