Cloud Storage
Храните просканированные страницы в управляемом хранилище Crawlbase. Извлекайте их позже по URL или RID. Без базы данных, без S3-бакета, без cron-задачи, которая всё это связывает.
Endpoint
# Two operations: store (write) and retrieve (read).
# Storage is implicit - set store=true on a Crawling API call to write.
# Use this endpoint to read.Сохранение страниц
Чтобы сохранить страницу, не нужно вызывать этот endpoint. Просто добавьте store=true к любому вызову Crawling API. Страница сохраняется автоматически, а в ответе вы получаете rid.
curl 'https://api.crawlbase.com/?token=YOUR_TOKEN' \
--data-urlencode 'url=https://example.com' \
--data-urlencode 'store=true' -G
# Response includes rid: a1B2c3D4e5F6import requests
res = requests.get(
'https://api.crawlbase.com/',
params={'token': 'YOUR_TOKEN', 'url': 'https://example.com', 'store': 'true'},
)
print(res.text)const params = new URLSearchParams({ token: 'YOUR_TOKEN', url: 'https://example.com', store: 'true' });
const res = await fetch(`https://api.crawlbase.com/?${params}`);
console.log(await res.text());require 'net/http'
uri = URI('https://api.crawlbase.com/')
uri.query = URI.encode_www_form(token: 'YOUR_TOKEN', url: 'https://example.com', store: 'true')
puts Net::HTTP.get(uri)Извлечение страниц
По RID
curl 'https://api.crawlbase.com/storage?token=YOUR_TOKEN&rid=a1B2c3D4e5F6'from crawlbase import StorageAPI
api = StorageAPI({'token': 'YOUR_TOKEN'})
res = api.get(rid='a1B2c3D4e5F6')
print(res['body'])const { StorageAPI } = require('crawlbase');
const api = new StorageAPI({ token: 'YOUR_TOKEN' });
const res = await api.get({ rid: 'a1B2c3D4e5F6' });
console.log(res.body);По URL
Найдите сохранённую страницу по её исходному URL. Возвращается самая свежая сохранённая версия.
curl 'https://api.crawlbase.com/storage?token=YOUR_TOKEN&url=https%3A%2F%2Fexample.com'import requests
res = requests.get(
'https://api.crawlbase.com/storage',
params={'token': 'YOUR_TOKEN', 'url': 'https://example.com'},
)
print(res.text)const params = new URLSearchParams({ token: 'YOUR_TOKEN', url: 'https://example.com' });
const res = await fetch(`https://api.crawlbase.com/storage?${params}`);
console.log(await res.text());require 'net/http'
uri = URI('https://api.crawlbase.com/storage')
uri.query = URI.encode_www_form(token: 'YOUR_TOKEN', url: 'https://example.com')
puts Net::HTTP.get(uri)Параметры
json оборачивает тело и метаданные.Массовое извлечение
Извлекайте до 100 сохранённых страниц за один round-trip по RID. Отправьте POST с JSON-телом со списком и (опционально) попросите сервер удалить каждую запись по мере её возврата - полезно для пайплайнов «осушения очереди», которым не нужно держать хранилище тёплым.
curl -X POST 'https://api.crawlbase.com/storage/bulk?token=YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ "rids": ["RID1","RID2","RID3"], "auto_delete": true }'import requests
res = requests.post(
'https://api.crawlbase.com/storage/bulk?token=YOUR_TOKEN',
json={'rids': ['RID1', 'RID2', 'RID3'], 'auto_delete': True},
)
print(res.json())const res = await fetch('https://api.crawlbase.com/storage/bulk?token=YOUR_TOKEN', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ rids: ['RID1', 'RID2', 'RID3'], auto_delete: true }),
});
console.log(await res.json());require 'json'
require 'net/http'
res = Net::HTTP.post(URI('https://api.crawlbase.com/storage/bulk?token=YOUR_TOKEN'),
{ rids: %w[RID1 RID2 RID3], auto_delete: true }.to_json,
'Content-Type' => 'application/json')
puts res.bodytrue , каждая успешно возвращённая запись удаляется из хранилища в том же вызове. Используйте это, когда осушаете очередь одноразовых результатов и не нуждаетесь в их хранении.Ответ - это JSON-массив, по одному объекту на возвращённый RID. Поле body закодировано в base64 и сжато gzip - декодируйте base64, затем распакуйте gzip, чтобы получить исходную страницу.
[
{
"stored_at": "2021-03-01T14:22:58+02:00",
"original_status": 200,
"cb_status": 200,
"rid": "RID1",
"url": "https://example.com/a",
"body": "H4sIAAAA…" // base64(gzip(html))
},
{
"stored_at": "2021-03-01T14:30:51+02:00",
"original_status": 200,
"cb_status": 200,
"rid": "RID2",
"url": "https://example.com/b",
"body": "H4sIAAAA…"
}
]Массовое удаление
Удалите список RID одним вызовом. Возвращает статус по каждому RID, так что вы увидите те, которых уже не было или удаление которых не удалось.
curl -X POST 'https://api.crawlbase.com/storage/bulk_delete?token=YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ "rids": ["RID1","RID2","RID3"] }'import requests
res = requests.post(
'https://api.crawlbase.com/storage/bulk_delete?token=YOUR_TOKEN',
json={'rids': ['RID1', 'RID2', 'RID3']},
)
print(res.json())const res = await fetch('https://api.crawlbase.com/storage/bulk_delete?token=YOUR_TOKEN', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ rids: ['RID1', 'RID2', 'RID3'] }),
});
console.log(await res.json());require 'json'
require 'net/http'
res = Net::HTTP.post(URI('https://api.crawlbase.com/storage/bulk_delete?token=YOUR_TOKEN'),
{ rids: %w[RID1 RID2 RID3] }.to_json,
'Content-Type' => 'application/json')
puts res.bodyОтвет представляет собой JSON-массив, по одной записи на каждый отправленный RID. status: true означает, что запись удалена; status: false с result: "Not Found" означает, что RID не существовал (уже был удалён, истёк срок или вообще не записывался).
[
{ "rid": "RID1", "result": "Deleted", "status": true },
{ "rid": "RID2", "result": "Not Found", "status": false },
{ "rid": "RID3", "result": "Failed", "status": false }
]Дважды проверьте список RID перед отправкой. Нет ни мягкого удаления, ни отмены - если вам нужен восстанавливаемый сценарий, сначала извлеките данные с auto_delete=false и вызывайте /bulk_delete только после того, как сохраните тело локально.
Удаление одной страницы
Удалите одну запись из хранилища по RID. Используйте DELETE /storage с RID в строке запроса.
curl -X DELETE 'https://api.crawlbase.com/storage?token=YOUR_TOKEN&rid=RID'import requests
res = requests.delete('https://api.crawlbase.com/storage?token=YOUR_TOKEN&rid=RID')
print(res.text)const res = await fetch('https://api.crawlbase.com/storage?token=YOUR_TOKEN&rid=RID', { method: 'DELETE' });
console.log(await res.text());require 'net/http'
uri = URI('https://api.crawlbase.com/storage?token=YOUR_TOKEN&rid=RID')
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.delete(uri.request_uri) }
puts res.bodyТри варианта ответа:
| Результат | Тело |
|---|---|
| Найдено и удалено | {"success": "The Storage item has been deleted successfully"} |
| Найдено, но удаление не удалось | {"error": "The Storage item could not be deleted"} |
| Нет в хранилище | {"error": "Not Found"} |
Список RID
Постранично перебирайте RID в вашей области хранения - инвентаризационный вызов. Для наборов данных, превышающих один ответ, используйте scroll-пагинацию ( scroll=true запускает scroll-сессию и возвращает scroll_id, который вы передаёте в последующих вызовах).
# First page
curl 'https://api.crawlbase.com/storage/rids?token=YOUR_TOKEN&limit=100&scroll=true'
# Next page - replay the scroll_id from the previous response
curl 'https://api.crawlbase.com/storage/rids?token=YOUR_TOKEN&scroll_id=dXVlcnlUaGVuRmV0Y2g7…'import requests
# First page
res = requests.get('https://api.crawlbase.com/storage/rids?token=YOUR_TOKEN&limit=100&scroll=true')
print(res.json())
# Next page - replay the scroll_id from the previous response
res = requests.get('https://api.crawlbase.com/storage/rids?token=YOUR_TOKEN&scroll_id=dXVlcnlUaGVuRmV0Y2g7…')
print(res.json())// First page
const first = await fetch('https://api.crawlbase.com/storage/rids?token=YOUR_TOKEN&limit=100&scroll=true');
console.log(await first.json());
// Next page - replay the scroll_id from the previous response
const next = await fetch('https://api.crawlbase.com/storage/rids?token=YOUR_TOKEN&scroll_id=dXVlcnlUaGVuRmV0Y2g7…');
console.log(await next.json());require 'net/http'
# First page
puts Net::HTTP.get(URI('https://api.crawlbase.com/storage/rids?token=YOUR_TOKEN&limit=100&scroll=true'))
# Next page - replay the scroll_id from the previous response
puts Net::HTTP.get(URI('https://api.crawlbase.com/storage/rids?token=YOUR_TOKEN&scroll_id=dXVlcnlUaGVuRmV0Y2g7…'))true , ответ включает scroll_id, который вы можете передать для получения следующей страницы. Без него вы получите только первую страницу.scroll=true в последующих запросах - только в первом вызове.{
"rids": ["RID1", "RID2", "RID3", "..."],
"scroll_id": "dXVlcnlUaGVuRmV0Y2g7NTs1NDpDV…"
}scroll_id действителен примерно 15 секунд бездействия. Если вы видите "Scroll session has expired or is invalid" , начните заново со свежего запроса с scroll=true - курсор уже потерян.
Общее количество
Одно целое число: сколько страниц сейчас находится в вашем хранилище.
curl 'https://api.crawlbase.com/storage/total_count?token=YOUR_TOKEN'
# Response
# { "totalCount": 5491078 }import requests
res = requests.get('https://api.crawlbase.com/storage/total_count?token=YOUR_TOKEN')
print(res.json())const res = await fetch('https://api.crawlbase.com/storage/total_count?token=YOUR_TOKEN');
console.log(await res.json());require 'net/http'
puts Net::HTTP.get(URI('https://api.crawlbase.com/storage/total_count?token=YOUR_TOKEN'))Хранение и тарификация
- Сохранённые страницы хранятся 30 дней по умолчанию . На enterprise-тарифах срок можно продлить.
- Каждый вызов с
store=trueсчитается одним запросом - без дополнительной платы. - Извлечение (этот endpoint) бесплатно . Читайте столько раз, сколько нужно.
- Если страница пересканируется с
store=true, новая версия заменяет старую.
Журналы аудита («что говорила страница, когда мы её сканировали?»), пайплайны переобработки (повторный парсинг сохранённого HTML, когда логика вашего скрапера улучшается) и отдача кэшированных результатов читателям без повторного сканирования.