# URL HTML 추출



입력한 URL의 HTML을 추출합니다.



인증: Authorization: Bearer $APICK_API_KEY

본문 있는 REST 요청: multipart/form-data. GET 본문 및 MCP JSON-RPC 규격은 해당 명세를 따릅니다.

인증키는 서버에 보관하세요. 모든 예제는 정적 자료입니다.



## POST /rest/url_html 응답 필드

- `data` (object): 요청 처리 결과 묶음입니다. 조회한 값·작업 상태·오류 설명이 이 안에 들어 있으며, 실제 하위 필드 구성은 서비스마다 다릅니다. 값이 없으면 null·빈 배열·필드 생략 중 해당 서비스의 규칙을 따릅니다.

- `data.search_result_page` (string): 검색 결과 페이지의 주소입니다. 요청한 검색어·페이지와 대응하며, 결과가 없으면 빈 문자열일 수 있습니다.

- `data.html` (string): 페이지의 HTML 전체입니다. 크기가 큰 페이지는 수 MB가 될 수 있습니다.

- `data.illegal_score` (integer): 페이지가 성인·도박·불법 복제·마약·사기 같은 불법·유해 서비스를 제공하거나 광고할 가능성 점수(0~100)입니다. 클수록 가능성이 높습니다.

- `data.illegal_category` (string): 점수가 50 이상일 때 가장 가까운 범주입니다. adult·gambling·piracy·drugs·fraud·other_crime, 해당 없으면 none입니다. 응답에 없을 수도 있으니 없으면 illegal_score만으로 판단하세요.

- `data.success` (integer): 업무 처리 결과 코드입니다. 1은 정상 결과, 0은 실패 또는 무료 응답입니다. 서비스에 따라 2·3처럼 추가 코드를 쓰므로 같은 응답의 status·msg·error 필드도 함께 확인하세요.

- `data.error` (string): 오류 원인을 설명하는 문구입니다. 성공 응답에는 없거나 빈 문자열입니다.

- `api` (object): API 호출 메타데이터입니다. 이번 요청의 서버 처리 성공 여부(api.success), 실제 차감 포인트(api.cost), 결제 기록 ID(api.pl_id)를 담습니다. 처리 시간(api.ms)은 응답에 포함된 경우에만 제공됩니다. 업무 결과는 data에서 확인합니다.

- `api.success` (boolean): API 서버가 이번 요청을 정상 처리했는지 여부입니다. true여도 업무 결과가 실패일 수 있으므로 data.success·data.status와 함께 판단합니다. 인증 실패·잘못된 입력·서버 오류 응답에서는 false입니다.

- `api.cost` (integer): 이번 호출에서 실제로 차감된 포인트입니다. 유료 성공 응답에서만 단가만큼 차감되며, 실패·무료 조회·같은 요청의 멱등 재전송은 0입니다. 화면의 표시 단가와 실제 차감액이 다를 수 있으므로 정산은 이 값을 기준으로 합니다.

- `api.ms` (integer): 서버가 요청을 받아 응답 본문을 만들기까지 걸린 처리 시간(밀리초)입니다. 네트워크 왕복 시간과 클라이언트 대기 시간은 포함되지 않습니다.

- `api.pl_id` (integer): 포인트 차감 기록 ID입니다. 차감이 발생한 호출에만 값이 있으며, 과금 내역을 문의할 때 이 번호를 사용합니다. 무과금 응답은 -1·null이거나 필드가 생략됩니다.

## API 요청: POST /rest/url_html



### 입력

- `url` (string, 필수): 조회할 대상의 URL입니다. http·https를 포함한 전체 주소를 보내며, 서비스에 따라 영상 ID만 받을 수도 있습니다.



### 응답 명세

```json

{
  "type": "object",
  "properties": {
    "data": {
      "type": "object",
      "properties": {
        "search_result_page": {
          "type": "string",
          "description": "최종 페이지 주소입니다. 리디렉션이 있었다면 요청한 url과 다릅니다."
        },
        "html": {
          "type": "string",
          "description": "페이지의 HTML 전체입니다. 크기가 큰 페이지는 수 MB가 될 수 있습니다."
        },
        "illegal_score": {
          "type": "integer",
          "description": "페이지가 성인·도박·불법 복제·마약·사기 같은 불법·유해 서비스를 제공하거나 광고할 가능성 점수(0~100)입니다. 클수록 가능성이 높습니다."
        },
        "illegal_category": {
          "type": "string",
          "description": "점수가 50 이상일 때 가장 가까운 범주입니다. adult·gambling·piracy·drugs·fraud·other_crime, 해당 없으면 none입니다. 응답에 없을 수도 있으니 없으면 illegal_score만으로 판단하세요."
        },
        "success": {
          "type": "integer",
          "description": "1이면 정상 처리되어 과금된 응답입니다. 시간 초과로 실패하면 3입니다."
        },
        "error": {
          "type": "string",
          "description": "실패 사유입니다. 이 필드가 있으면 과금되지 않습니다."
        }
      }
    },
    "api": {
      "type": "object",
      "properties": {
        "success": {
          "type": "boolean"
        },
        "cost": {
          "type": "integer",
          "description": "차감된 포인트입니다. 실패하면 0입니다."
        },
        "ms": {
          "type": "integer"
        },
        "pl_id": {
          "type": "integer",
          "description": "결제 기록 번호입니다."
        }
      }
    }
  }
}

```

### 정적 응답 예시

```json

{
  "data": {
    "search_result_page": "https://apick.app/",
    "html": "<!DOCTYPE html><html lang=\"ko\"><head><meta charset=\"utf-8\"><title>에이픽</title></head><body>…</body></html>",
    "illegal_score": 2,
    "illegal_category": "none",
    "success": 1
  },
  "api": {
    "success": true,
    "cost": 5,
    "ms": 4551,
    "pl_id": 3022117
  }
}

```

### curl

```curl

curl --fail-with-body --request POST 'https://apick.app/rest/url_html' \
  --header "Authorization: Bearer $APICK_API_KEY" \
  --form-string 'url=https://apick.app'

```

### Node.js (서버 ESM)

```javascript

const form = new FormData();
form.append("url", "https://apick.app");
const response = await fetch("https://apick.app/rest/url_html", {
  method: "POST",
  headers: { Authorization: "Bearer " + process.env.APICK_API_KEY },
  body: form,
  signal: AbortSignal.timeout(120_000),
});
if (!response.ok) throw new Error(`HTTP ${response.status}: ${await response.text()}`);
const result = await response.json();
console.log(result);

```

### python

```python

import os
import requests
parts = [
    ("url", (None, "https://apick.app")),
]
response = requests.request("POST", "https://apick.app/rest/url_html",
    headers={"Authorization": "Bearer " + os.environ["APICK_API_KEY"]},
    files=parts,
    timeout=(10, 120))
response.raise_for_status()
result = response.json()
print(result)

```

### php

```php

<?php
$headers = ["Authorization: Bearer " . getenv("APICK_API_KEY")];
$form = [
    'url' => 'https://apick.app',
];
$curl = curl_init('https://apick.app/rest/url_html');
curl_setopt_array($curl, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_HTTPHEADER => $headers,
    CURLOPT_POSTFIELDS => $form,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 120,
]);
$body = curl_exec($curl);
if ($body === false) { throw new RuntimeException(curl_error($curl)); }
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
if ($status >= 400) { throw new RuntimeException($body); }
$result = json_decode($body, true, 512, JSON_THROW_ON_ERROR);
print_r($result);

```

## 사용 예시 1. 페이지 HTML 가져오기

페이지의 메타 태그·본문을 분석할 때 HTML 전체를 받습니다.

```bash

curl --fail-with-body --request POST 'https://apick.app/rest/url_html' \
  --header "Authorization: Bearer $APICK_API_KEY" \
  --form-string 'url=https://apick.app'

```

- `data.html`이 HTML 전체이고, `data.search_result_page`가 리디렉션 뒤 최종 주소입니다.

- 시간이 초과되면 `data.success`가 3이며 과금되지 않습니다.

## 사용 예시 2. 유해 사이트 선별

신고된 링크가 불법·유해 사이트인지 1차로 걸러 낼 때 씁니다.

```bash

curl --fail-with-body --request POST 'https://apick.app/rest/url_html' \
  --header "Authorization: Bearer $APICK_API_KEY" \
  --form-string 'url=https://example.com/promo'

```

- `data.illegal_score`(0~100)가 기준값 이상이면 검토 대상으로 표시합니다.

- `data.illegal_category`가 있으면 범주(`adult`·`gambling`·`piracy` 등)를 함께 기록합니다.

- 점수만으로 삭제·차단처럼 되돌릴 수 없는 처리를 하지 말고 사람이 확인합니다.

## 코드·오류

### 업무 실패 응답

입력 오류·대상 없음·일시 실패는 data.error(사유)와 data.success=0으로 오며 api.cost는 0(과금 없음)입니다. HTTP 상태는 400·404·408·424 중 하나입니다. 입력 오류는 값을 고쳐 다시 요청하고, 408·424는 잠시 후 한 번 다시 시도하세요.

```json

{
  "data": {
    "error": "입력값을 확인해 주세요.",
    "success": 0
  },
  "api": {
    "success": true,
    "cost": 0,
    "ms": 5
  }
}

```

## 상세 기능·요금

이용 전 확인 웹 페이지 주소를 보내면 그 페이지의 HTML 전체와 리디렉션을 거친 최종 주소, 불법·유해 사이트 가능성 점수를 돌려줍니다. 페이지 내용 분석, 메타 태그 확인, 변경 감시, 유해 사이트 선별에 씁니다. 추출에 성공하면 한 건당 5P가 차감됩니다. 실패하거나 시간이 초과되면 data.error로 응답하며 과금되지 않습니다. http·https로 시작하는 공개 인터넷 주소만 받습니다. 사내망·사설 IP·localhost 주소와 로그인해야 보이는 페이지는 추출할 수 없습니다. 응답까지 길면 30초 가까이 걸립니다. 클라이언트 대기 시간은 60초 이상으로 두세요.

## 상세 요청

항목설정 메서드·주소POST https://apick.app/rest/url_html 인증 헤더Authorization: Bearer — 내 계정의 API 인증키 본문 형식multipart/form-data 요청 예시 form-data 전체 예제 보기

## 상세 응답

필드타입설명 data.htmlstring페이지의 HTML 전체입니다. 크기가 큰 페이지는 수 MB가 될 수 있습니다. data.search_result_pagestring최종 페이지 주소입니다. 리디렉션이 있었다면 요청한 url과 다릅니다. data.illegal_scoreinteger페이지가 성인·도박·불법 복제·마약·사기 같은 불법·유해 서비스를 제공하거나 광고할 가능성 점수(0~100)입니다. 클수록 가능성이 높습니다. data.illegal_categorystring점수가 50 이상일 때 가장 가까운 범주입니다. adult·gambling·piracy·drugs·fraud·other_crime, 해당 없으면 none입니다. 응답에 없을 수도 있으니 없으면 illegal_score만으로 판단하세요. data.successinteger1이면 정상 처리되어 과금된 응답입니다. 시간 초과로 실패하면 3입니다. data.errorstring실패 사유입니다. 이 필드가 있으면 과금되지 않습니다. api.costinteger차감된 포인트입니다. 실패하면 0입니다. api.pl_idinteger결제 기록 번호입니다. { "data": { "search_result_page": "https://apick.app/", "html": "<!DOCTYPE html><html lang=\"ko\"><head><meta charset=\"utf-8\"><title>에이픽</title></head><body>…</body></html>", "illegal_score": 2, "illegal_category": "none", "success": 1 }, "api": { "success": true, "cost": 5, "ms": 4551, "pl_id": 3022117 } } 유해 사이트를 걸러 낼 때는 illegal_score가 일정 값(예: 70) 이상인지로 판단하고, 범주가 필요하면 illegal_category를 함께 보세요. 이 점수만으로 결제·삭제처럼 되돌릴 수 없는 처리를 하지 말고 사람이 확인하는 단계를 두세요.

## 상세 코드·정책

오류 코드 data.errorHTTP대처 필수 입력값이 없습니다.400url을 채워 다시 요청합니다. 알 수 없는 이유로 실패했습니다.424주소가 http·https가 아니거나, 공개 인터넷 주소가 아니거나, 페이지가 열리지 않은 경우입니다. 브라우저에서 주소가 열리는지 확인한 뒤 다시 요청합니다. 처리 시간 초과로 실패했습니다. 잠시후 다시 시도해 주세요.408data.success가 3입니다. 잠시 뒤 다시 요청합니다. 오류 응답은 모두 api.cost가 0이며 과금되지 않습니다.
