Spaces:
Paused
Paused
| <html lang="zh-CN"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>ScraperProxy API</title> | |
| <style> | |
| :root { | |
| --primary-color: #3498db; | |
| --secondary-color: #2980b9; | |
| --accent-color: #e74c3c; | |
| --text-color: #333; | |
| --light-bg: #f5f7fa; | |
| --card-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); | |
| } | |
| * { | |
| margin: 0; | |
| padding: 0; | |
| box-sizing: border-box; | |
| } | |
| body { | |
| font-family: Arial, sans-serif; | |
| line-height: 1.6; | |
| color: var(--text-color); | |
| background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); | |
| min-height: 100vh; | |
| } | |
| .container { | |
| max-width: 60%; | |
| margin: 0 auto; | |
| padding: 20px; | |
| } | |
| header { | |
| text-align: center; | |
| margin-bottom: 40px; | |
| padding: 20px; | |
| background-color: white; | |
| border-radius: 10px; | |
| box-shadow: var(--card-shadow); | |
| } | |
| h1 { | |
| color: var(--primary-color); | |
| margin-bottom: 10px; | |
| font-size: 2.5rem; | |
| } | |
| h2 { | |
| color: var(--primary-color); | |
| margin: 25px 0 15px; | |
| font-size: 1.8rem; | |
| } | |
| .subtitle { | |
| font-size: 1.2rem; | |
| color: #666; | |
| margin-bottom: 20px; | |
| } | |
| pre, .code-block { | |
| background-color: #282c34; | |
| color: #abb2bf; | |
| padding: 20px; | |
| border-radius: 6px; | |
| overflow-x: auto; | |
| font-family: 'Courier New', Courier, monospace; | |
| margin: 15px 0; | |
| white-space: pre-wrap; | |
| } | |
| .features { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); | |
| gap: 20px; | |
| margin-bottom: 40px; | |
| } | |
| .feature-card { | |
| background-color: white; | |
| padding: 25px; | |
| border-radius: 10px; | |
| box-shadow: var(--card-shadow); | |
| transition: transform 0.3s ease; | |
| } | |
| .feature-card:hover { | |
| transform: translateY(-5px); | |
| } | |
| .feature-card h3 { | |
| color: var(--primary-color); | |
| margin-bottom: 15px; | |
| font-size: 1.4rem; | |
| } | |
| .section { | |
| background-color: white; | |
| padding: 30px; | |
| border-radius: 10px; | |
| box-shadow: var(--card-shadow); | |
| margin-bottom: 30px; | |
| } | |
| .button { | |
| display: inline-block; | |
| background-color: var(--primary-color); | |
| color: white; | |
| padding: 12px 24px; | |
| border-radius: 6px; | |
| text-decoration: none; | |
| font-weight: bold; | |
| transition: background-color 0.3s ease; | |
| margin: 10px 5px; | |
| border: none; | |
| cursor: pointer; | |
| } | |
| .button:hover { | |
| background-color: var(--secondary-color); | |
| } | |
| .button.accent { | |
| background-color: var(--accent-color); | |
| } | |
| .button.accent:hover { | |
| background-color: #c0392b; | |
| } | |
| .input-group { | |
| margin-bottom: 20px; | |
| } | |
| .input-group label { | |
| display: block; | |
| margin-bottom: 8px; | |
| font-weight: bold; | |
| } | |
| .input-group input[type="text"] { | |
| width: 100%; | |
| padding: 12px; | |
| border: 1px solid #ddd; | |
| border-radius: 6px; | |
| font-size: 16px; | |
| } | |
| .checkbox-group { | |
| margin: 15px 0; | |
| } | |
| #response-container { | |
| background-color: #f5f5f5; | |
| padding: 20px; | |
| border-radius: 6px; | |
| min-height: 100px; | |
| margin-top: 20px; | |
| white-space: pre-wrap; | |
| display: none; | |
| } | |
| ul { | |
| list-style-position: inside; | |
| margin: 10px 0; | |
| } | |
| ul li { | |
| margin-bottom: 5px; | |
| } | |
| footer { | |
| text-align: center; | |
| margin-top: 40px; | |
| padding: 20px; | |
| color: #666; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <header> | |
| <h1>ScraperProxy API</h1> | |
| <p class="subtitle">强大的网页请求代理服务,轻松绕过访问限制</p> | |
| <div> | |
| <a href="/docs" class="button">API 文档</a> | |
| <a href="#try-it" class="button accent">立即尝试</a> | |
| </div> | |
| </header> | |
| <div class="section"> | |
| <h2>支持的请求库</h2> | |
| <p>这是一个支持两种强大请求库的代理服务:</p> | |
| <ul> | |
| <li><strong>CloudScraper</strong> - 专门用于绕过 Cloudflare 保护</li> | |
| <li><strong>curl-cffi</strong> - 高性能的 cURL 实现</li> | |
| </ul> | |
| </div> | |
| <div class="features"> | |
| <div class="feature-card"> | |
| <h3>绕过访问限制</h3> | |
| <p>使用专业技术,轻松绕过常见的网站防护机制,如 Cloudflare 的反爬虫保护。</p> | |
| </div> | |
| <div class="feature-card"> | |
| <h3>支持流式响应</h3> | |
| <p>通过流式响应处理大型数据,保持连接稳定,实现更高效的数据传输。</p> | |
| </div> | |
| <div class="feature-card"> | |
| <h3>简单易用</h3> | |
| <p>简洁的 API 设计,只需一个 URL 参数即可使用,支持多种请求方法和自定义选项。</p> | |
| </div> | |
| </div> | |
| <div class="section"> | |
| <h2>使用方法</h2> | |
| <p>基本请求格式:</p> | |
| <pre>GET /proxy?url=https://example.com | |
| POST /proxy?url=https://example.com</pre> | |
| <h3>环境变量配置</h3> | |
| <ul> | |
| <li><strong>REQUEST_LIB</strong>: 选择请求库 (cloudscraper 或 curl_cffi)</li> | |
| <li><strong>PROXY</strong>: 设置代理服务器</li> | |
| <li><strong>TOKEN</strong>: 设置访问令牌</li> | |
| </ul> | |
| <h3>高级用法示例</h3> | |
| <div class="code-block"># 启用流式响应 | |
| GET /proxy?url=https://example.com&stream=true | |
| # 自定义请求方法和头信息 | |
| POST /proxy | |
| { | |
| "url": "https://example.com", | |
| "method": "POST", | |
| "headers": {"Custom-Header": "Value"}, | |
| "data": {"key": "value"}, | |
| "stream": true | |
| }</div> | |
| </div> | |
| <div class="section" id="try-it"> | |
| <h2>立即尝试</h2> | |
| <div class="input-group"> | |
| <label for="url-input">输入要请求的 URL:</label> | |
| <input type="text" id="url-input" placeholder="https://example.com" value="https://example.com"> | |
| </div> | |
| <div class="checkbox-group"> | |
| <input type="checkbox" id="stream-checkbox" checked> | |
| <label for="stream-checkbox">启用流式响应</label> | |
| </div> | |
| <button id="send-request" class="button">发送请求</button> | |
| <div id="response-container"></div> | |
| </div> | |
| </div> | |
| <footer> | |
| <p>© 2025 ScraperProxy API. 所有权利保留。</p> | |
| </footer> | |
| <script> | |
| document.getElementById('send-request').addEventListener('click', async function() { | |
| const url = document.getElementById('url-input').value; | |
| const streamEnabled = document.getElementById('stream-checkbox').checked; | |
| const responseContainer = document.getElementById('response-container'); | |
| if (!url) { | |
| alert('请输入有效的 URL'); | |
| return; | |
| } | |
| responseContainer.style.display = 'block'; | |
| responseContainer.textContent = '正在加载...'; | |
| try { | |
| const proxyUrl = `/proxy?url=${encodeURIComponent(url)}&stream=${streamEnabled}`; | |
| if (streamEnabled) { | |
| responseContainer.textContent = ''; | |
| const response = await fetch(proxyUrl); | |
| const reader = response.body.getReader(); | |
| while (true) { | |
| const { done, value } = await reader.read(); | |
| if (done) break; | |
| const text = new TextDecoder().decode(value); | |
| responseContainer.textContent += text; | |
| } | |
| } else { | |
| const response = await fetch(proxyUrl); | |
| const data = await response.text(); | |
| responseContainer.textContent = data; | |
| } | |
| } catch (error) { | |
| responseContainer.textContent = `错误: ${error.message}`; | |
| } | |
| }); | |
| </script> | |
| </body> | |
| </html> | |