本文摘要 DeepSeek
该工具用于下载网页内容,操作步骤为:输入完整 URL 并点击 「开始扒」,完成后可下载 ZIP 文件或预览。注意事项包括禁止违法违规使用、避免频繁操作同一站点,且仅限公开网页,版权归源站所有。核心代码展示了后端处理流程:验证 URL 有效性,创建任务 ID 和访问令牌,下载网页内容并压缩为 ZIP 文件,最后更新任务状态。代码包含错误处理,确保权限和磁盘空间充足,并提供友好的错误提示。
使用说明:
- 输入完整的网页 URL 例如:https://example.com
- 点击 "开始扒" 按钮,等待系统执行!
- 提示 "扒完了",点击 「下载 ZIP 文件」 或 「预览成果」
注意:禁止用于违法、违规使用,禁止频繁对同一站点使用,只能扒公开可访问的网页,版权归源站点所有,你所扒取的或下载的仅供本地测试学习。
核心代码示例:
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (empty($_POST['url'])) {
ob_end_clean();
header('Content-Type: application/json');
echo json_encode(['success' => false, 'message' => 'URL 不能为空'], JSON_UNESCAPED_UNICODE);
exit;
}
$url = filter_var($_POST['url'], FILTER_VALIDATE_URL);
if (!$url) {
ob_end_clean();
header('Content-Type: application/json');
echo json_encode(['success' => false, 'message' => '无效的 URL'], JSON_UNESCAPED_UNICODE);
exit;
}
try {
$parsedUrl = parse_url($url);
$domain = str_replace(['.', ':'], '_', $parsedUrl['host'] ?? 'unknown');
$saveDir = "$downloadsDir/$domain";
if (is_dir($saveDir)) {
deleteDirectory($saveDir);
}
if (!mkdir($saveDir, 0777, true)) {
throw new Exception('无法创建域名目录,可能是权限不足或磁盘空间已满。');
}
// 生成任务 ID 和访问令牌
$taskId = uniqid('task_', true);
$accessToken = bin2hex(random_bytes(16));
$statusFile = "$statusDir/$taskId.json";
updateStatus($statusFile, [
'progress' => 0,
'status' => '初始化',
'files' => [],
'completed' => false,
'accessToken' => $accessToken
]);
$downloader = new WebsiteDownloader($url, $saveDir, $taskId, $statusFile);
$downloader->download();
$zipFilename = "$domain.zip";
$zipPath = "$downloadsDir/$zipFilename";
$zip = new ZipArchive();
if ($zip->open($zipPath, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== true) {
throw new Exception('无法创建 ZIP 文件,可能是权限不足或磁盘空间已满。');
}
$files = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($saveDir, FilesystemIterator::SKIP_DOTS),
RecursiveIteratorIterator::LEAVES_ONLY
);
$fileCount = 0;
foreach ($files as $file) {
if (!$file->isDir()) {
$filePath = $file->getRealPath();
if (!file_exists($filePath)) {
error_log("文件 $filePath 不存在,跳过。");
continue;
}
$relativePath = substr($filePath, strlen($saveDir) + 1);
if (!$zip->addFile($filePath, $relativePath)) {
error_log("无法添加文件 $filePath 到 ZIP 文件,错误信息: " . $zip->getStatusString());
} else {
$fileCount++;
}
}
}
if (!$zip->close()) {
throw new Exception('无法保存 ZIP 文件,可能是文件被占用或磁盘空间不足。错误信息: ' . $zip->getStatusString());
}
$fileSize = filesize($zipPath);
$previewUrl = "preview.php?taskId=" . urlencode($taskId);
updateStatus($statusFile, [
'progress' => 100,
'status' => '下载完成',
'files' => [],
'completed' => true,
'filename' => $zipFilename,
'fileCount' => $fileCount,
'fileSize' => $fileSize,
'previewUrl' => $previewUrl,
'accessToken' => $accessToken,
'domain' => $domain
]);
ob_end_clean();
echo json_encode([
'success' => true,
'message' => '任务已启动',
'taskId' => $taskId
], JSON_UNESCAPED_UNICODE);
} catch (Exception $e) {
if (isset($statusFile)) {
updateStatus($statusFile, [
'progress' => 0,
'status' => '错误: ' . $e->getMessage(),
'files' => [],
'completed' => false,
'accessToken' => $accessToken
]);
}
ob_end_clean();
header('Content-Type: application/json');
$friendlyError = getFriendlyErrorMessage($e->getMessage());
echo json_encode(['success' => false, 'message' => $friendlyError], JSON_UNESCAPED_UNICODE);
}
exit;
}