> ## Documentation Index
> Fetch the complete documentation index at: https://docs.adscrawl.net/llms.txt
> Use this file to discover all available pages before exploring further.

# PHP SDK for AdsCrawl

> 安装并使用 AdsCrawl PHP SDK 获取渲染内容、截图、结构化数据并管理远程 CDP 会话。支持 PHP 8.1+，仅需标准 JSON 和 cURL 扩展。

AdsCrawl PHP SDK 适用于 PHP 8.1 及以上版本。它仅需标准 JSON 和 cURL 扩展，使用显式 HTTP 超时机制，并返回凭证脱敏的错误信息。

<Note>
  请将 API 密钥保存在服务端代码中。切勿在客户端应用中暴露 API 密钥。
</Note>

## 安装

```bash theme={null}
composer require adscrawl/adscrawl
```

<Card title="adscrawl-php on GitHub" icon="github" href="https://github.com/AdsCrawl/adscrawl-php">
  查看源代码、可运行示例和发布版本。
</Card>

## 认证并发起首次请求

在控制台中[创建 API 密钥](https://app.adscrawl.net/register/?utm_source=packagist\&utm_medium=sdk\&utm_campaign=adscrawl-php)，并在服务器环境中设置 `ADSCRAWL_API_KEY`。你也可以将密钥直接传递给 `new Client(apiKey: '...')`。

```php theme={null}
<?php

require __DIR__ . '/vendor/autoload.php';

use AdsCrawl\Client;

$client = new Client();
$markdown = $client->markdown([
    'url' => 'https://www.adscrawl.net',
    'waitUntil' => 'domcontentloaded',
]);
echo $markdown;
```

## 渲染内容与截图

```php theme={null}
<?php

require __DIR__ . '/vendor/autoload.php';

use AdsCrawl\Client;

$client = new Client();
$html = $client->html(['url' => 'https://www.adscrawl.net']);
$article = $client->article(['url' => 'https://www.adscrawl.net']);
echo $article['title'] . "\n" . $article['textContent'];

$png = $client->screenshot([
    'url' => 'https://www.adscrawl.net',
    'viewport' => ['width' => 1440, 'height' => 900],
    'fullPage' => true,
    'waitUntil' => 'load',
]);
file_put_contents('page.png', $png);
```

`html()` 返回 HTML，`markdown()` 返回 Markdown，`article()` 返回关联数组，`screenshot()` 返回 PNG 字节流。页面选项包括 `viewport`、`locale`、`cookies`、自定义 `proxy`、托管的 `countryCode`、`fingerprint`、服务端 `timeoutMs` 以及导航 `waitUntil`。自定义代理与托管国家/地区不能同时使用。

## 代理与指纹

```php theme={null}
<?php

require __DIR__ . '/vendor/autoload.php';

use AdsCrawl\Client;

$client = new Client();
$server = getenv('ADSCRAWL_PROXY_SERVER') ?: null;
$username = getenv('ADSCRAWL_PROXY_USERNAME') ?: null;
$password = getenv('ADSCRAWL_PROXY_PASSWORD') ?: null;
if (($username === null) !== ($password === null)) {
    throw new RuntimeException('Set both proxy username and password, or neither.');
}
if ($server === null && ($username !== null || $password !== null)) {
    throw new RuntimeException('Set ADSCRAWL_PROXY_SERVER with proxy credentials.');
}

$routing = ['countryCode' => 'GLOBAL'];
if ($server !== null) {
    $proxy = ['server' => $server];
    if ($username !== null && $password !== null) {
        $proxy += ['username' => $username, 'password' => $password];
    }
    $routing = ['proxy' => $proxy];
}

$png = $client->screenshot([
    'url' => 'https://www.browserscan.net/',
    ...$routing,
    'viewport' => ['width' => 1440, 'height' => 900],
    'fullPage' => true,
    'waitUntil' => 'networkidle',
    'timeoutMs' => 60_000,
    'userAgentMode' => 'random',
    'userAgentOs' => 'windows',
    'fingerprint' => [
        'webRtc' => 'forward', 'webGl' => 'random', 'webGpu' => 'random',
        'webGlImage' => 'random', 'canvas' => 'random',
        'audioContext' => 'random', 'clientRects' => 'random',
        'speechVoices' => 'random', 'fonts' => 'random',
        'hardware' => 'random', 'doNotTrack' => 'random',
    ],
], timeoutMs: 75_000);
file_put_contents('browserscan.png', $png);
```

AdsCrawl 使用真实浏览器，支持可配置的路由和浏览器指纹。随机设置会生成一个覆盖操作系统、GPU、硬件、字体及相关信号的统一配置。该浏览器工作流已经过验证，可以访问并渲染 BrowserScan、Pixelscan 和 IPhey，并返回截图。

## 结构化提取

```php theme={null}
<?php

require __DIR__ . '/vendor/autoload.php';

use AdsCrawl\Client;

$client = new Client();
print_r($client->spa->templates()['templates']);

$result = $client->spa->extract([
    'url' => 'https://www.adscrawl.net',
    'fields' => [
        'title' => ['source' => 'dom', 'selector' => 'h1', 'value' => 'text', 'required' => true],
    ],
]);
echo $result['data']['title'];

$inspection = $client->spa->inspect(['url' => 'https://www.adscrawl.net']);
print_r($inspection['candidates']);
```

## 远程 CDP 浏览器

```php theme={null}
<?php

require __DIR__ . '/vendor/autoload.php';

use AdsCrawl\Client;

$client = new Client();
$session = $client->cdp->create([
    'idleTimeoutMs' => 600_000,
    'maxSessionMs' => 3_600_000,
    'browserSettings' => ['viewport' => ['width' => 1440, 'height' => 900]],
]);
try {
    $version = $client->cdp->getVersion($session);
    echo $version['Browser'];
    // Connect a CDP-compatible PHP library to $session['cdpBaseUrl'].
} finally {
    $client->cdp->close($session['sessionId']);
}
```

`$client->cdp->list()` 返回活跃会话列表。`getVersion()` 验证会话令牌 URL，并故意不携带 API 密钥。CDP 连接 URL 包含敏感信息，请勿将其记录到日志中。

## 持久化云浏览器

```php theme={null}
<?php

require __DIR__ . '/vendor/autoload.php';

use AdsCrawl\Client;

$client = new Client();
$launched = $client->cloudBrowsers->launch([
    'proxy' => ['server' => getenv('ADSCRAWL_PROXY_SERVER')],
    'tabs' => ['https://www.adscrawl.net'],
]);
$browserId = $launched['id'];
try {
    $profile = $client->cloudBrowsers->get($browserId);
    echo $profile['runtime']['status'];
} finally {
    $client->cloudBrowsers->stop($browserId);
}
```

API 密钥启动要求显式设置顶层自定义代理。`stopping` 响应表示关闭正在等待中，请轮询 `get()` 直到状态变为 `stopped`。启动失败时，清理配置文件的 ID 可能作为 `ApiException::$resourceId` 暴露。

## 配置与错误处理

```php theme={null}
<?php

require __DIR__ . '/vendor/autoload.php';

use AdsCrawl\Client;
use AdsCrawl\Exception\ApiException;
use AdsCrawl\Exception\TimeoutException;

$client = new Client(baseUrl: 'https://api.adscrawl.net', timeoutMs: 90_000);
try {
    echo $client->markdown(
        ['url' => 'https://www.adscrawl.net', 'timeoutMs' => 60_000],
        timeoutMs: 75_000,
    );
} catch (ApiException $error) {
    echo $error->status . ' ' . $error->apiCode . ' ' . $error->traceId;
} catch (TimeoutException) {
    echo 'Inspect remote sessions before retrying.';
}
```

API 密钥默认为 `ADSCRAWL_API_KEY`。基础 URL 默认依次为 `ADSCRAWL_BASE_URL`、`ADSCRAWL_API_URL`，然后是 `https://api.adscrawl.net`。错误类型包括 `ApiException`、`TimeoutException`、`ConnectionException` 和 `ResponseException`。API 响应体会进行凭证脱敏处理。HTTP 超时时间包含响应体的读取。请求不会自动重试。
