Nanny7's picture
initial deploy
bcf46c3
Raw
History Blame Contribute Delete
3.21 kB
#!/usr/bin/env node
import { Command } from 'commander';
import dotenv from 'dotenv';
import path from 'path';
import { OpticparseClient, ScrapeRequest } from './index';
// Load default environment variables from the current working directory's .env file
dotenv.config();
const program = new Command();
program
.name('opticparse')
.description('Command-line utility to scrape dynamic web pages using AI Vision & Gemini.')
.version('1.0.0');
program
.command('scrape')
.description('Execute a visual scrape operation against a webpage.')
.requiredOption('-u, --url <string>', 'The URL of the webpage to scrape.')
.requiredOption('-q, --query <string>', 'The structured query explaining what JSON data to extract.')
.option('-k, --key <string>', 'API key credential. Falls back to OPTICPARSE_API_KEY env variable.')
.option('-a, --api-url <string>', 'Custom target API server host URL.')
.option('--width <number>', 'Browser viewport width.', '1280')
.option('--height <number>', 'Browser viewport height.', '800')
.option('--wait-until <string>', 'Playwright wait criteria: networkidle, load, or domcontentloaded.', 'networkidle')
.option('-t, --timeout <number>', 'Scraper connection & execution timeout in milliseconds.', '90000')
.action(async (options) => {
try {
const apiKey = options.key || process.env.OPTICPARSE_API_KEY;
const apiUrl = options.apiUrl || process.env.OPTICPARSE_API_URL;
if (!apiKey) {
console.error('\x1b[31mError: API Key is missing.\x1b[0m');
console.error('Please specify the key using the -k/--key flag, or set the OPTICPARSE_API_KEY environment variable.');
process.exit(1);
}
const client = new OpticparseClient({
apiKey,
apiUrl,
});
const scrapeRequest: ScrapeRequest = {
targetUrl: options.url,
extractionQuery: options.query,
viewportWidth: parseInt(options.width, 10),
viewportHeight: parseInt(options.height, 10),
waitUntil: options.waitUntil as any,
timeout: parseInt(options.timeout, 10),
};
console.log(`\x1b[36mInitiating visual scraping of:\x1b[0m ${options.url}`);
console.log(`\x1b[36mQuery:\x1b[0m "${options.query}"`);
const startTime = Date.now();
const result = await client.scrape(scrapeRequest);
const duration = ((Date.now() - startTime) / 1000).toFixed(2);
console.log(`\x1b[32mSuccessfully scraped in ${duration}s!\x1b[0m`);
console.log('\n\x1b[35m=== Extracted JSON Result ===\x1b[0m');
console.log(JSON.stringify(result, null, 2));
console.log('\x1b[35m=============================\x1b[0m');
} catch (error: any) {
console.error('\n\x1b[31m=== Scraper Execution Failed ===\x1b[0m');
console.error(`\x1b[31mMessage:\x1b[0m ${error.message}`);
if (error.statusCode) {
console.error(`\x1b[31mHTTP Status Code:\x1b[0m ${error.statusCode}`);
}
if (error.details) {
console.error(`\x1b[31mServer Details:\x1b[0m ${error.details}`);
}
console.error('\x1b[31m================================\x1b[0m');
process.exit(1);
}
});
program.parse(process.argv);