Запуск и остановка профилей
Введение
Vision предоставляет возможность запуска и остановки профилей по API, используя HTTP-запросы. Для отправки некоторых запросов может потребоваться X-Token, подробнее о нём можно прочитать в соответствующей статье.
Работа с профилями
Получение списка запущенных профилей
В Vision есть возможность получения информации по уже запущенным профилям.
Запрос
Для получения списка запущенных профилей необходимо отправить соответствующий GET запрос:
Пример запроса
const url = "http://127.0.0.1:3030/list"; const options = { method: "GET", headers: { "X-Token": "Your Token", }, };fetch(url, options) .then((response) => { response.json().then((data) => { console.log(data); }); }) .catch((error) => { console.error(error); });import requestsurl = 'http://127.0.0.1:3030/list' headers = { 'X-Token': 'Your Token', 'Content-Type': 'application/json'}response = requests.get(url, headers=headers)print(response.json())<?php$url = "http://127.0.0.1:3030/list";$token = "Your Token"; $headers = array( 'X-Token: '.$token, 'Content-Type: application/json');$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);$data = curl_exec($ch);if (curl_errno($ch)) { print "Error: " . curl_error($ch);} else { var_dump($data); curl_close($ch);}?>// Requires tokio with features = ["macros", "rt-multi-thread"]// Requires reqwest with features = ["json"]// Requires serde_json#[tokio::main]async fn main() { let url = "http://127.0.0.1:3030/list"; let token = "Token"; let client = reqwest::Client::new(); let response = client .get(url) .header("X-Token", token) .send() .await .expect("Failed to send request") .json::<serde_json::Value>() .await .expect("Failed to parse response"); dbg!(response);}package mainimport ( "io" "net/http")func main() { url := "http://127.0.0.1:3030/list" token := "Your Token" client := http.Client{} req, err := http.NewRequest("GET", url, nil) if err != nil { panic(err) } req.Header.Add("X-Token", token) resp, err := client.Do(req) if err != nil { panic(err) } defer resp.Body.Close() body, _ := io.ReadAll(resp.Body) println(string(body))}var url = "http://127.0.0.1:3030/list";var token = "Your Token"; var client = new HttpClient();client.DefaultRequestHeaders.Add("X-Token", token);var response = await client.GetAsync(url);var content = await response.Content.ReadAsStringAsync();Console.WriteLine(content);Пример ответа
{
"profiles": [
{
"folder_id": "698d2698-11a5-4768-bfb8-92b904026bfd",
"profile_id": "05296821-1ee5-445c-805f-1523578e898c",
"port": null
},
{
"folder_id": "698d2698-11a5-4768-bfb8-92b904026bfd",
"profile_id": "98bc0cb8-3cae-483f-bb8c-2607cc5c9883",
"port": null
},
{
"folder_id": "698d2698-11a5-4768-bfb8-92b904026bfd",
"profile_id": "9c6ed4a3-20b3-441d-adc6-58b99791f67b",
"port": null
}
]
}Запуск профиля по API
Запрос
Для запуска профиля необходимо отправить соответствующий GET запрос:
Обратите внимание, что в URL запроса неободимо передать ID папки - folderId, в которой находится запускаемый профиль, а также ID самого профиля - profileID.
Если вы хотите передать дополнительные аргументы в браузер, вы можете сделать это, отправив POST запрос с JSON телом, содержащим поле args с массивом аргументов.
Заголовки запроса
Prop
Type
Тело запроса (необязательно)
Prop
Type
Пример запроса
const url = "http://127.0.0.1:3030/start/{folderId}/{profileId}"; const options = { method: "GET", headers: { "X-Token": "Your Token", }, };fetch(url, options) .then((response) => { response.json().then((data) => { console.log(data); }); }) .catch((error) => { console.error(error); });import requestsurl = 'http://127.0.0.1:3030/start/{folderId}/{profileId}' headers = { 'X-Token': 'Your Token', 'Content-Type': 'application/json'}response = requests.get(url, headers=headers)print(response.json())<?php$url = "http://127.0.0.1:3030/start/{folderId}/{profileId}";$token = "Your Token"; $headers = array( 'X-Token: '.$token, 'Content-Type: application/json');$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);$data = curl_exec($ch);if (curl_errno($ch)) { print "Error: " . curl_error($ch);} else { var_dump($data); curl_close($ch);}?>// Requires tokio with features = ["macros", "rt-multi-thread"]// Requires reqwest with features = ["json"]// Requires serde_json#[tokio::main]async fn main() { let url = "http://127.0.0.1:3030/start/{folderId}/{profileId}"; let token = "Token"; let client = reqwest::Client::new(); let response = client .get(url) .header("X-Token", token) .send() .await .expect("Failed to send request") .json::<serde_json::Value>() .await .expect("Failed to parse response"); dbg!(response);}package mainimport ( "io" "net/http")func main() { url := "http://127.0.0.1:3030/start/{folderId}/{profileId}" token := "Your Token" client := http.Client{} req, err := http.NewRequest("GET", url, nil) if err != nil { panic(err) } req.Header.Add("X-Token", token) resp, err := client.Do(req) if err != nil { panic(err) } defer resp.Body.Close() body, _ := io.ReadAll(resp.Body) println(string(body))}var url = "http://127.0.0.1:3030/start/{folderId}/{profileId}";var token = "Your Token"; var client = new HttpClient();client.DefaultRequestHeaders.Add("X-Token", token);var response = await client.GetAsync(url);var content = await response.Content.ReadAsStringAsync();Console.WriteLine(content);Пример запроса запуска профиля в режиме headless
const url = "http://127.0.0.1:3030/start/{folderId}/{profileId}"; const body = { "args": [ "--headless" ]}const options = { method: "POST", headers: { "X-Token": "Your Token", "Content-Type": "application/json" }, body: JSON.stringify(body)};fetch(url, options) .then((response) => { response.json().then((data) => { console.log(data); }); }) .catch((error) => { console.error(error); });import requestsurl = 'http://127.0.0.1:3030/start/{folderId}/{profileId}' body = { "args": [ "--headless" ]}headers = { 'X-Token': 'Your Token', 'Content-Type': 'application/json'}response = requests.post(url, headers=headers, json=body)print(response.json())<?php$url = "http://127.0.0.1:3030/start/{folderId}/{profileId}";$token = "Your Token"; $body = '{ "args": [ "--headless" ]}';$headers = array( 'X-Token: '.$token, 'Content-Type: application/json');$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);curl_setopt($ch, CURLOPT_POSTFIELDS, $body);$data = curl_exec($ch);if (curl_errno($ch)) { print "Error: " . curl_error($ch);} else { var_dump($data); curl_close($ch);}?>// Requires tokio with features = ["macros", "rt-multi-thread"]// Requires reqwest with features = ["json"]// Requires serde_json#[tokio::main]async fn main() { let url = "http://127.0.0.1:3030/start/{folderId}/{profileId}"; let token = "Token"; let body = serde_json::json!( { "args": [ "--headless" ] } ); let client = reqwest::Client::new(); let response = client .post(url) .header("X-Token", token) .json(&body) .send() .await .expect("Failed to send request") .json::<serde_json::Value>() .await .expect("Failed to parse response"); dbg!(response);}package mainimport ( "bytes" "io" "net/http")func main() { url := "http://127.0.0.1:3030/start/{folderId}/{profileId}" token := "Your Token" body := []byte(` { "args": [ "--headless" ] } `) client := http.Client{} req, err := http.NewRequest("POST", url, nil) if err != nil { panic(err) } req.Header.Add("X-Token", token) req.Header.Add("Content-Type", "application/json") req.Body = io.NopCloser(bytes.NewReader(body)) resp, err := client.Do(req) if err != nil { panic(err) } defer resp.Body.Close() body, _ := io.ReadAll(resp.Body) println(string(body))}var url = "http://127.0.0.1:3030/start/{folderId}/{profileId}";var token = "Your Token"; var body = """{ "args": [ "--headless" ]}"""var client = new HttpClient();client.DefaultRequestHeaders.Add("X-Token", token);client.DefaultRequestHeaders.Add("Content-Type", "application/json");var contentBody = new StringContent(body, Encoding.UTF8, "application/json");var response = await client.PostAsync(url, contentBody);var content = await response.Content.ReadAsStringAsync();Console.WriteLine(content);Пример запроса запуска профиля с конкретным портом
В указанном ниже примере вместо PORT_NUMBER_HERE необходимо указать целое число в диапазоне от 1024 до 65535. Таким образом профиль будет запущен с указанным в коде портом, а вы сможете использовать именно этот порт для подключения к инстансу браузерного профиля.
const url = "http://127.0.0.1:3030/start/{folderId}/{profileId}"; const body = { "args": [ "--remote-debugging-port=PORT_NUMBER_HERE" ]}const options = { method: "POST", headers: { "X-Token": "Your Token", "Content-Type": "application/json" }, body: JSON.stringify(body)};fetch(url, options) .then((response) => { response.json().then((data) => { console.log(data); }); }) .catch((error) => { console.error(error); });import requestsurl = 'http://127.0.0.1:3030/start/{folderId}/{profileId}' body = { "args": [ "--remote-debugging-port=PORT_NUMBER_HERE" ]}headers = { 'X-Token': 'Your Token', 'Content-Type': 'application/json'}response = requests.post(url, headers=headers, json=body)print(response.json())<?php$url = "http://127.0.0.1:3030/start/{folderId}/{profileId}";$token = "Your Token"; $body = '{ "args": [ "--remote-debugging-port=PORT_NUMBER_HERE" ]}';$headers = array( 'X-Token: '.$token, 'Content-Type: application/json');$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);curl_setopt($ch, CURLOPT_POSTFIELDS, $body);$data = curl_exec($ch);if (curl_errno($ch)) { print "Error: " . curl_error($ch);} else { var_dump($data); curl_close($ch);}?>// Requires tokio with features = ["macros", "rt-multi-thread"]// Requires reqwest with features = ["json"]// Requires serde_json#[tokio::main]async fn main() { let url = "http://127.0.0.1:3030/start/{folderId}/{profileId}"; let token = "Token"; let body = serde_json::json!( { "args": [ "--remote-debugging-port=PORT_NUMBER_HERE" ] } ); let client = reqwest::Client::new(); let response = client .post(url) .header("X-Token", token) .json(&body) .send() .await .expect("Failed to send request") .json::<serde_json::Value>() .await .expect("Failed to parse response"); dbg!(response);}package mainimport ( "bytes" "io" "net/http")func main() { url := "http://127.0.0.1:3030/start/{folderId}/{profileId}" token := "Your Token" body := []byte(` { "args": [ "--remote-debugging-port=PORT_NUMBER_HERE" ] } `) client := http.Client{} req, err := http.NewRequest("POST", url, nil) if err != nil { panic(err) } req.Header.Add("X-Token", token) req.Header.Add("Content-Type", "application/json") req.Body = io.NopCloser(bytes.NewReader(body)) resp, err := client.Do(req) if err != nil { panic(err) } defer resp.Body.Close() body, _ := io.ReadAll(resp.Body) println(string(body))}var url = "http://127.0.0.1:3030/start/{folderId}/{profileId}";var token = "Your Token"; var body = """{ "args": [ "--remote-debugging-port=PORT_NUMBER_HERE" ]}"""var client = new HttpClient();client.DefaultRequestHeaders.Add("X-Token", token);client.DefaultRequestHeaders.Add("Content-Type", "application/json");var contentBody = new StringContent(body, Encoding.UTF8, "application/json");var response = await client.PostAsync(url, contentBody);var content = await response.Content.ReadAsStringAsync();Console.WriteLine(content);Пример запроса запуска профиля с временной прокси
Если необходимо запустить профиль с временной прокси, то можно указать данные от прокси в теле запроса на запуск. При этом данная прокси сохранена не будет. От вас потребуется передать в body запроса следующие данные:
- тип прокси (http, https, socks5, ssh)
- хост прокси (IP адрес или домен)
- порт
- логин (при наличии)
- пароль (при наличии)
ВАЖНО: Для запуска профиля с временной прокси параметр args должен быть передан в любом случае.
Если аргументы есть — укажите их в массиве.
Если аргументов нет — передайте пустой массив (args: []), иначе запуск не выполнится.
const url = "http://127.0.0.1:3030/start/{folderId}/{profileId}"; const body = { "args": [], "proxy": { "type": "socks5", "address": "1.1.1.1", "port": 4123, "username": "vision", "password": "password" }}const options = { method: "POST", headers: { "X-Token": "Your Token", "Content-Type": "application/json" }, body: JSON.stringify(body)};fetch(url, options) .then((response) => { response.json().then((data) => { console.log(data); }); }) .catch((error) => { console.error(error); });import requestsurl = 'http://127.0.0.1:3030/start/{folderId}/{profileId}' body = { "args": [], "proxy": { "type": "socks5", "address": "1.1.1.1", "port": 4123, "username": "vision", "password": "password" }}headers = { 'X-Token': 'Your Token', 'Content-Type': 'application/json'}response = requests.post(url, headers=headers, json=body)print(response.json())<?php$url = "http://127.0.0.1:3030/start/{folderId}/{profileId}";$token = "Your Token"; $body = '{ "args": [], "proxy": { "type": "socks5", "address": "1.1.1.1", "port": 4123, "username": "vision", "password": "password" }}';$headers = array( 'X-Token: '.$token, 'Content-Type: application/json');$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);curl_setopt($ch, CURLOPT_POSTFIELDS, $body);$data = curl_exec($ch);if (curl_errno($ch)) { print "Error: " . curl_error($ch);} else { var_dump($data); curl_close($ch);}?>// Requires tokio with features = ["macros", "rt-multi-thread"]// Requires reqwest with features = ["json"]// Requires serde_json#[tokio::main]async fn main() { let url = "http://127.0.0.1:3030/start/{folderId}/{profileId}"; let token = "Token"; let body = serde_json::json!( { "args": [], "proxy": { "type": "socks5", "address": "1.1.1.1", "port": 4123, "username": "vision", "password": "password" } } ); let client = reqwest::Client::new(); let response = client .post(url) .header("X-Token", token) .json(&body) .send() .await .expect("Failed to send request") .json::<serde_json::Value>() .await .expect("Failed to parse response"); dbg!(response);}package mainimport ( "bytes" "io" "net/http")func main() { url := "http://127.0.0.1:3030/start/{folderId}/{profileId}" token := "Your Token" body := []byte(` { "args": [], "proxy": { "type": "socks5", "address": "1.1.1.1", "port": 4123, "username": "vision", "password": "password" } } `) client := http.Client{} req, err := http.NewRequest("POST", url, nil) if err != nil { panic(err) } req.Header.Add("X-Token", token) req.Header.Add("Content-Type", "application/json") req.Body = io.NopCloser(bytes.NewReader(body)) resp, err := client.Do(req) if err != nil { panic(err) } defer resp.Body.Close() body, _ := io.ReadAll(resp.Body) println(string(body))}var url = "http://127.0.0.1:3030/start/{folderId}/{profileId}";var token = "Your Token"; var body = """{ "args": [], "proxy": { "type": "socks5", "address": "1.1.1.1", "port": 4123, "username": "vision", "password": "password" }}"""var client = new HttpClient();client.DefaultRequestHeaders.Add("X-Token", token);client.DefaultRequestHeaders.Add("Content-Type", "application/json");var contentBody = new StringContent(body, Encoding.UTF8, "application/json");var response = await client.PostAsync(url, contentBody);var content = await response.Content.ReadAsStringAsync();Console.WriteLine(content);Обратите внимание, что временная прокси является приоритетным выбором при запуске.
Это значит, что при наличии у профиля привязанной прокси, запуск всё равно произойдёт с временной прокси.
Ответ
Данные ответа
Prop
Type
Пример ответа
{
"folder_id": "698d2698-11a5-4768-bfb8-92b904026bfd",
"profile_id": "98bc0cb8-3cae-483f-bb8c-2607cc5c9883",
"port": 19512
}Остановка профиля по API
Запрос
Для остановки профиля необходимо отправить соответствующий GET запрос:
Обратите внимание, что в URL запроса необходимо передать ID папки - folderId, в которой находится останавливаемый профиль, а также ID самого профиля - profileId.
Пример запроса
const url = "http://127.0.0.1:3030/stop/{folderId}/{profileId}"; const options = { method: "GET", headers: { "X-Token": "Your Token", }, };fetch(url, options) .then((response) => { response.json().then((data) => { console.log(data); }); }) .catch((error) => { console.error(error); });import requestsurl = 'http://127.0.0.1:3030/stop/{folderId}/{profileId}' headers = { 'X-Token': 'Your Token', 'Content-Type': 'application/json'}response = requests.get(url, headers=headers)print(response.json())<?php$url = "http://127.0.0.1:3030/stop/{folderId}/{profileId}";$token = "Your Token"; $headers = array( 'X-Token: '.$token, 'Content-Type: application/json');$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);$data = curl_exec($ch);if (curl_errno($ch)) { print "Error: " . curl_error($ch);} else { var_dump($data); curl_close($ch);}?>// Requires tokio with features = ["macros", "rt-multi-thread"]// Requires reqwest with features = ["json"]// Requires serde_json#[tokio::main]async fn main() { let url = "http://127.0.0.1:3030/stop/{folderId}/{profileId}"; let token = "Token"; let client = reqwest::Client::new(); let response = client .get(url) .header("X-Token", token) .send() .await .expect("Failed to send request") .json::<serde_json::Value>() .await .expect("Failed to parse response"); dbg!(response);}package mainimport ( "io" "net/http")func main() { url := "http://127.0.0.1:3030/stop/{folderId}/{profileId}" token := "Your Token" client := http.Client{} req, err := http.NewRequest("GET", url, nil) if err != nil { panic(err) } req.Header.Add("X-Token", token) resp, err := client.Do(req) if err != nil { panic(err) } defer resp.Body.Close() body, _ := io.ReadAll(resp.Body) println(string(body))}var url = "http://127.0.0.1:3030/stop/{folderId}/{profileId}";var token = "Your Token"; var client = new HttpClient();client.DefaultRequestHeaders.Add("X-Token", token);var response = await client.GetAsync(url);var content = await response.Content.ReadAsStringAsync();Console.WriteLine(content);Ответ
Пример ответа
Stopping profile 98bc0cb8-3cae-483f-bb8c-2607cc5c9883 in folder 698d2698-11a5-4768-bfb8-92b904026bfd