novada/sdk
Composer 安装命令:
composer require novada/sdk
包简介
Official PHP SDK for the Novada API (proxy management, scraping, wallet).
README 文档
README
PHP SDK for the Novada API — proxy management, scraping, and wallet endpoints. PHP 8.1+, PSR-18/PSR-17 HTTP client agnostic (no Guzzle hard dependency).
Install
composer require novada/sdk
The SDK talks HTTP through PSR-18 (psr/http-client) and PSR-17 factories, discovered automatically via php-http/discovery. If your project doesn't already have a PSR-18 client installed, pull in Guzzle:
composer require guzzlehttp/guzzle
You can also inject your own PSR-18 client/PSR-17 factories via ClientConfig — see Configuration below.
Quick start
<?php declare(strict_types=1); require __DIR__ . '/vendor/autoload.php'; use Novada\Client; use Novada\Proxy\Dto\ListWhitelistParams; use Novada\Proxy\Product; $client = new Client('YOUR_API_KEY'); // or null to read NOVADA_API_KEY $list = $client->proxy->whitelist->list(new ListWhitelistParams( product: Product::Residential, )); printf("whitelist total=%d\n", $list->total);
Configuration
use Novada\Client; use Novada\ClientConfig; $client = new Client('API_KEY', new ClientConfig( baseUrl: 'https://api-m.novada.com', webUnblockerUrl: 'https://webunlocker.novada.com', scraperUrl: 'https://scraper.novada.com', timeout: 30.0, maxRetries: 2, httpClient: $psr18Client, // optional: inject your own PSR-18 client requestFactory: $psr17Factory, // optional: inject your own PSR-17 request factory streamFactory: $psr17Factory, // optional: inject your own PSR-17 stream factory userAgent: 'my-app/1.0', ));
All fields are optional and have production defaults. The Bearer API key is injected on every request. Retries apply only to network errors and HTTP 429/5xx — never to a non-zero business code.
The three base URLs
Novada serves requests from three hosts. All are configurable via ClientConfig and default to production:
| Purpose | Default | Used by |
|---|---|---|
| General | https://api-m.novada.com |
Every /v1/* endpoint (proxy, wallet, and the scraper area/balance/unit queries) |
| Web Unblocker | https://webunlocker.novada.com |
$client->scraper->unblocker->scrape() (typed), or ->scraper->do() with Target::WebUnblocker |
| Scraper API | https://scraper.novada.com |
->scraper->do() / ->scraper->api->* with Target::ScraperApi |
Only the scrape POST /request calls go to the Web Unblocker / Scraper API hosts; everything else (/v1/*) uses the general host.
Proxy
use Novada\Proxy\Dto\{AddWhitelistParams, CreateAccountParams, ListAccountParams, ListWhitelistParams, OpenStaticIspParams, TimeRange}; use Novada\Proxy\Product; // Sub-accounts $client->proxy->account->create(new CreateAccountParams( product: Product::Residential, account: 'account11', password: 'pass11', status: 1, )); $client->proxy->account->list(new ListAccountParams(product: Product::Residential)); // Whitelist $client->proxy->whitelist->add(new AddWhitelistParams( product: Product::Residential, ip: '10.10.10.1', remark: 'test', )); $client->proxy->whitelist->list(new ListWhitelistParams(product: Product::Residential)); // Residential areas & traffic $client->proxy->residential->countries(); $client->proxy->residential->balance(); $client->proxy->residential->consumeLog(new TimeRange( start: '2025-01-01 00:00:00', end: '2025-01-31 23:59:59', )); // Static ISP / dedicated datacenter $client->proxy->staticIsp->open(new OpenStaticIspParams( ipType: 'normal', region: 'hk:1|us-va:2', duration: 'week', num: 3, )); $client->proxy->dedicatedDc->list(new \Novada\Proxy\Dto\ListStaticParams());
Sub-services: account, whitelist, residential, mobile, rotatingIsp, rotatingDc, staticIsp, dedicatedDc, unlimited, prohibitDomain. Required parameters are validated client-side and reported as a Novada\Exception\ValidationException before any request is sent.
Scraper
use Novada\Scraper\Dto\{GoogleSearchParams, Request as ScrapeRequest, UnblockerParams, YouTubeVideoParams}; use Novada\Scraper\Target; // Strongly typed (auto-selects the Scraper API host) $res = $client->scraper->api->youtube->videoPost(new YouTubeVideoParams( url: 'https://www.youtube.com/watch?v=HAwTwmzgNc4', )); // Google Search (SerpApi) — typed params, structured result ($result->data->json is the raw result array) $gs = $client->scraper->api->google->search(new GoogleSearchParams( query: 'apple', country: 'us', // device, hl, renderJs, aiOverview, … optional )); printf("%d %d\n", $gs->code, $gs->costTime); // Generic driver — any scraper_id, choose the host explicitly $res = $client->scraper->do(new ScrapeRequest( target: Target::ScraperApi, // or Target::WebUnblocker scraperName: 'youtube.com', scraperId: 'youtube_video-post_explore', params: [['url' => 'https://www.youtube.com/watch?v=HAwTwmzgNc4']], returnErrors: true, )); echo $res->raw; // raw scrape result (JSON/CSV/XLSX, depending on scraper) // Web Unblocker — typed scrape; returns a structured result, not raw text $unb = $client->scraper->unblocker->scrape(new UnblockerParams( targetUrl: 'https://www.google.com', // required country: 'us', // responseFormat defaults to "html" )); printf("%d %d %f\n", $unb->code, strlen($unb->html), $unb->useBalance); // Query endpoints on the general host $client->scraper->universal->balance(); // /v1/capture/get_balance $client->scraper->universal->unit(); // /v1/capture/unit $client->scraper->unblocker->countries(); // /v1/proxy/unblocker_area $client->scraper->browser->countries(); // /v1/proxy/browser_area
$client->scraper->do() JSON-encodes params, places it in the scraper_params form field, URL-encodes the body, and routes to the host selected by target. Scrape responses are returned raw because their format varies by scraper. $client->scraper->unblocker->scrape() is the dedicated Web Unblocker call: it sends the endpoint's own fields (target_url, response_format, js_render, country, wait_ms, …) and decodes the JSON envelope into a structured UnblockerResult (html, code, msg, msgDetail, useBalance).
Wallet
use Novada\Wallet\Dto\UsageRecordParams; $client->wallet->balance(); $client->wallet->usageRecord(new UsageRecordParams(page: 1, limit: 20));
Error handling
Management endpoints return a uniform envelope {code, data, msg, timestamp}; only code === 0 is success. A non-zero code or a non-2xx HTTP status becomes a Novada\Exception\ApiException.
use Novada\Exception\ApiException; use Novada\Exception\AuthException; use Novada\Exception\RateLimitException; use Novada\Proxy\Dto\ListWhitelistParams; use Novada\Proxy\Product; try { $list = $client->proxy->whitelist->list(new ListWhitelistParams(product: Product::Residential)); } catch (AuthException $e) { // HTTP 401/403 error_log('invalid API key'); } catch (RateLimitException $e) { // HTTP 429 error_log('rate limited'); } catch (ApiException $e) { // any other API error, business code in getCode() error_log(sprintf('business error code=%d: %s', $e->getCode(), $e->getMsg())); }
Examples
Runnable examples live in examples/: proxy.php, scraper.php, wallet.php. Set NOVADA_API_KEY and run e.g. php examples/proxy.php.
Development
composer install composer stan # PHPStan, level max composer cs # PHP-CS-Fixer, dry run composer cs-fix # PHP-CS-Fixer, apply fixes composer test # PHPUnit
License
统计信息
- 总下载量: 0
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 1
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-07-11