# Renderização de JS e controle do navegador

## Renderização de JavaScript

Se a página que você deseja extrair exigir JavaScript para carregar dinamicamente todos os dados necessários no DOM, você pode incluir um `render` parâmetro em suas requisições em vez de configurar e usar manualmente instruções personalizadas do navegador. As requisições com esse parâmetro serão renderizadas بالكامل, e os dados serão armazenados em um arquivo HTML ou em uma captura de tela PNG, dependendo do parâmetro especificado.

### HTML

Defina o `render` parâmetro para `html` para obter a saída bruta da página renderizada.

### PNG (Captura de tela)

Defina o `render` parâmetro para `png` para obter uma captura de tela codificada em Base64 da página renderizada.

{% hint style="info" %}
Se você quiser extrair uma imagem e baixá-la, consulte [**esta seção**](/products/pt-br/web-scraper-api/features/result-processing-and-storage/output-types/download-images.md)**.**
{% endhint %}

### Exemplo de solicitação

{% tabs %}
{% tab title="cURL" %}

```shell
curl --user "user:pass" \\
'https://realtime.oxylabs.io/v1/queries' \\
-H "Content-Type: application/json" \
-d '{"source": "universal", "url": "https://www.example.com", "render": "html"}'
```

{% endtab %}

{% tab title="Python" %}

```python
import requests
from pprint import pprint

# Estruture o payload.
payload = {
    'source': 'universal',
    'url': 'https://www.example.com',
    'render': 'html',
}

# Obtenha a response.
response = requests.request(
    'POST',
    'https://realtime.oxylabs.io/v1/queries',
    auth=('user', 'pass1'),
    json=payload,
)

# Em vez de uma resposta com status do job e URL dos resultados, isso retornará o
# resposta JSON com o resultado.
pprint(response.json())
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php

$params = [
    'source' => 'universal',
    'url' => 'https://www.example.com',
    'render' => 'html',
];

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "https://realtime.oxylabs.io/v1/queries");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($params));
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, "user" . ":" . "pass1");

$headers = array();
$headers[] = "Content-Type: application/json";
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
echo $result;

if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
```

{% endtab %}

{% tab title="C#" %}

```csharp
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Json;
using System.Threading.Tasks;

namespace OxyApi
{
    class Program
    {
        static async Task Main()
        {
            const string Username = "YOUR_USERNAME";
            const string Password = "YOUR_PASSWORD";

            var parameters = new Dictionary<string, string>()
            {
                { "source", "universal" },
                { "url", "https://www.example.com" },
                { "render" : "html" },
            };


            var client = new HttpClient();

            Uri baseUri = new Uri("https://realtime.oxylabs.io");
            client.BaseAddress = baseUri;

            var requestMessage = new HttpRequestMessage(HttpMethod.Post, "/v1/queries");
            requestMessage.Content = JsonContent.Create(parameters);

            var authenticationString = $"{Username}:{Password}";
            var base64EncodedAuthenticationString = Convert.ToBase64String(System.Text.ASCIIEncoding.UTF8.GetBytes(authenticationString));
            requestMessage.Headers.Add("Authorization", "Basic " + base64EncodedAuthenticationString);

            var response = await client.SendAsync(requestMessage);
            var contents = await response.Content.ReadAsStringAsync();

            Console.WriteLine(contents);
        }
    }
}
```

{% endtab %}

{% tab title="Golang" %}

```go
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
)

func main() {
	const Username = "YOUR_USERNAME"
	const Password = "YOUR_PASSWORD"

	payload := map[string]string{
		"source": "universal",
		"url": "https://www.example.com",
        	"render": "html",
	}

	jsonValue, _ := json.Marshal(payload)

	client := &http.Client{}
	request, _ := http.NewRequest("POST",
		"https://realtime.oxylabs.io/v1/queries",
		bytes.NewBuffer(jsonValue),
	)

	request.SetBasicAuth(Username, Password)
	response, _ := client.Do(request)

	responseText, _ := ioutil.ReadAll(response.Body)
	fmt.Println(string(responseText))
}
```

{% endtab %}

{% tab title="Java" %}

```java
package org.example;

import okhttp3.*;
import org.json.JSONObject;

public class Main implements Runnable {
    private static final String AUTHORIZATION_HEADER = "Authorization";
    public static final String USERNAME = "YOUR_USERNAME";
    public static final String PASSWORD = "YOUR_PASSWORD";

    public void run() {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("source", "universal");
        jsonObject.put("url", "https://www.example.com");
        jsonObject.put("render": "html");

        Authenticator authenticator = (route, response) -> {
            String credential = Credentials.basic(USERNAME, PASSWORD);

            return response
                    .request()
                    .newBuilder()
                    .header(AUTHORIZATION_HEADER, credential)
                    .build();
        };

        var client = new OkHttpClient.Builder()
                .authenticator(authenticator)
                .build();

        var mediaType = MediaType.parse("application/json; charset=utf-8");
        var body = RequestBody.create(jsonObject.toString(), mediaType);
        var request = new Request.Builder()
                .url("https://realtime.oxylabs.io/v1/queries")
                .post(body)
                .build();

        try (var response = client.newCall(request).execute()) {
            assert response.body() != null;
            System.out.println(response.body().string());
        } catch (Exception exception) {
            System.out.println("Error: " + exception.getMessage());
        }

        System.exit(0);
    }

    public static void main(String[] args) {
        new Thread(new Main()).start();
    }
}
```

{% endtab %}

{% tab title="Node.js" %}

```javascript
import fetch from 'node-fetch';

const username = 'YOUR_USERNAME';
const password = 'YOUR_PASSWORD';
const body = {
  'source': 'universal',
  'url': 'https://www.example.com',
  'render': 'html'
};
const response = await fetch('https://realtime.oxylabs.io/v1/queries', {
  method: 'post',
  body: JSON.stringify(body),
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Basic ' + Buffer.from(`${username}:${password}`).toString('base64'),
  }
});

console.log(await response.json());
```

{% endtab %}

{% tab title="HTTP" %}

```http
# A string inteira que você enviar precisa estar codificada em URL.

https://realtime.oxylabs.io/v1/queries?source=universal&url=https%3A%2F%2Fwww.example.com%2F&render=html&access_token=12345abcde
```

{% endtab %}

{% tab title="JSON" %}

```json
{
    "source": "universal", 
    "url": "https://www.example.com", 
    "render": "html"
}
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
A renderização de JavaScript leva mais tempo para extrair a página. Defina o timeout no lado do cliente para 180 segundos se estiver usando Realtime ou Proxy Endpoint métodos de integração.
{% endhint %}

{% hint style="warning" %}
Para garantir o menor consumo de tráfego possível, nosso sistema não carrega ativos desnecessários durante a renderização da página.
{% endhint %}

## Forçando a renderização em páginas específicas

Para uma extração bem-sucedida, alguns tipos de página de domínios específicos exigem renderização devido ao conteúdo dinâmico. Nosso sistema aplica automaticamente a renderização para essas páginas, mesmo que não seja definida explicitamente pelo usuário.

{% hint style="warning" %}
Observe que trabalhos renderizados consomem mais tráfego em comparação com trabalhos não renderizados.
{% endhint %}

Queremos que nossos usuários estejam totalmente cientes disso ao extrair as seguintes páginas:

{% file src="/files/46ce7bd0a1b786eeca394cd4cd386302d553fe30" %}

Essa abordagem oferece a melhor experiência de extração possível, garantindo a precisão e a confiabilidade dos dados nessas páginas desafiadoras.&#x20;

Se você quiser desativar a renderização, pode fazer isso adicionando o seguinte parâmetro às suas requisições:

```
"render": ""
```

## Instruções do navegador

Você pode definir suas próprias instruções do navegador que são executadas ao renderizar JavaScript.

{% hint style="success" %}
A maneira mais fácil de configurar instruções do navegador é usando o criador visual de instruções de navegador com IA no [Web Scraper API Playground](https://dashboard.oxylabs.io/?route=/api-playground). Leia sobre isso [aqui](/products/pt-br/web-scraper-api/web-scraper-api-playground/oxycopilot.md#browser-instruction-builder).
{% endhint %}

### Uso

Para usar instruções do navegador, forneça um conjunto de `browser_instructions` ao criar uma tarefa.

Digamos que você queira pesquisar o termo `pizza boxes` em um site.

<figure><img src="/files/80c1fd5a9c03dba369512e1cbb1edd069bd64d48" alt=""><figcaption></figcaption></figure>

Um exemplo de parâmetros da tarefa seria o seguinte:

```json
{
    "source": "universal",
    "url": "https://www.ebay.com/",
    "render": "html",
    "browser_instructions": [
        {
            "type": "input",
            "value": "caixas de pizza",
            "selector": {
                "type": "xpath",
                "value": "//input[@class='gh-tb ui-autocomplete-input']"
            }
        },
        {
            "type": "click",
            "selector": {
                "type": "xpath",
                "value": "//input[@type='submit']"
            }
        },
        {
            "type": "wait",
            "wait_time_s": 5
        }
    ]
}
```

**Etapa 1.** Você deve fornecer o `"render": "html"` parâmetro.

**Etapa 2.** As instruções do navegador devem ser descritas no campo `"browser_instructions"` .

As instruções de exemplo acima especificam que o objetivo é inserir um termo de pesquisa `pizza boxes` em um campo de pesquisa, clicar no botão `pesquisar` e esperar 5 segundos para o conteúdo carregar.

O resultado coletado deve ser o seguinte:

```json
{
  "results": [
    {
      "content": "<!doctype html><html>
        Conteúdo após executar as instruções      
      </html>",
      "created_at": "2023-10-11 11:35:23",
      "updated_at": "2023-10-11 11:36:08",
      "page": 1,
      "url": "https://www.ebay.com/",
      "job_id": "7117835067442906113",
      "status_code": 200
    }
  ]
}
```

O HTML coletado deve ser assim:

<figure><img src="/files/f79c6a098d7bc794c7bf8b71bc9baa9281fd36c3" alt=""><figcaption></figcaption></figure>

#### Obtendo recursos do navegador <a href="#fetching-browser-resources" id="fetching-browser-resources"></a>

Fornecemos uma instrução independente do navegador para obter recursos do navegador.

A função é definida aqui:

Usando `fetch_resource` resultará na tarefa retornando a primeira ocorrência de um recurso Fetch/XHR que corresponda ao formato fornecido, em vez do HTML que está sendo alvo.

Digamos que queremos direcionar um recurso GraphQL que é obtido ao visitar uma página de produto organicamente no navegador. Forneceremos as informações da tarefa assim:

```json
{
    "source": "universal",
    "url": "https://www.example.com/product-page/123",
    "render": "html",
    "browser_instructions": [
        {
            "type": "fetch_resource",
            "filter": "/graphql/product-info/123"
        }
    ]
}
```

Essas instruções resultarão em um resultado assim:

```json
{
  "results": [
    {
      "content": "{'product_id': 123, 'description': '', 'price': 123}",
      "created_at": "2023-10-11 11:35:23",
      "updated_at": "2023-10-11 11:36:08",
      "page": 1,
      "url": "https://example.com/v1/graphql/product-info/123/",
      "job_id": "7117835067442906114",
      "status_code": 200
    }
  ]
}
```

## Lista de instruções de navegador suportadas <a href="#list-of-supported-browser-instructions" id="list-of-supported-browser-instructions"></a>

### Argumentos gerais

Todas as instruções definidas abaixo têm um conjunto consistente de argumentos. Os argumentos são os seguintes.

#### `type` <a href="#type" id="type"></a>

* **Tipo**: `Enum["click", "input", "scroll", "scroll_to_bottom", "wait", "wait_for_element", "fetch_resource"]`
* **Descrição:** Tipo de instrução do navegador.

#### `timeout_s` <a href="#timeout_s" id="timeout_s"></a>

* **Tipo**: `int`
* **Descrição:** Quanto tempo até a ação ser ignorada se não for concluída a tempo.
* **Restrições**: 0 < `timeout_s` <= 60
* **Valor padrão**: 5

#### `wait_time_s` <a href="#wait_time_s" id="wait_time_s"></a>

* **Tipo**: `int`
* **Descrição:** Quanto tempo esperar antes de executar a próxima ação.
* **Restrições**: 0 < `wait_time_s` <= 60
* **Valor padrão**: 0

#### `on_error` <a href="#on_error" id="on_error"></a>

* **Tipo**: `Enum["error", "skip"]`
* **Descrição:** Indicador do que fazer com as instruções caso esta instrução falhe:
  * `"error"`: Interrompe a execução das instruções do navegador.
  * `"skip"`: Continua com a próxima instrução.
* **Valor padrão**: `"error"`

#### Exemplo com argumentos gerais

```json
{
    "type": "wait_for_element",
    "selector": {
        "type": "text",
        "value": "Carregar mais itens"
    },
    "timeout_s": 5,
    "wait_time_s": 2,
    "on_error": "skip"

}
```

### Instruções <a href="#click" id="click"></a>

#### `click` <a href="#click" id="click"></a>

* **Descrição**: Clica em um elemento e espera um número definido de segundos.
* **Args:**
  * `type: str = "click"`
  * `selector: dict`
    * `type: Enum["xpath", "css", "text"]`
    * `value: str`

**Exemplo**:

```json
{
    "type": "click",
    "selector": {
        "type": "xpath",
        "value": "//button"
    }
}
```

#### `input` <a href="#input" id="input"></a>

* **Descrição**: Insere um texto em um elemento selecionado.
* **Args:**
  * `type: str = "input"`
  * `selector: dict`
    * `type: Enum["xpath", "css", "text"]`
    * `value: str`
  * `value: str`&#x20;

**Exemplo:**

```json
{
    "type": "input",
    "selector": {
        "type": "xpath",
        "value": "//input"
    },
    "value": "caixas de pizza"
}
```

#### `scroll` <a href="#scroll" id="scroll"></a>

* **Descrição**: Rola um número definido de pixels.
* **Args:**
  * `type: str = "scroll"`
  * `x: int`
  * `y: int`

**Exemplo:**

```json
{
    "type": "scroll",
    "x": 0,
    "y": 100
}
```

#### `scroll_to_bottom` <a href="#scroll_to_bottom" id="scroll_to_bottom"></a>

* **Descrição**: Rola até o fim por um número definido de segundos.
* **Args:**
  * `type: str = "scroll_to_bottom"`

**Exemplo**:

```json
{
    "type": "scroll_to_bottom",
    "timeout_s": 10
}
```

#### `wait` <a href="#wait" id="wait"></a>

* **Descrição**: Espera um número definido de segundos.
* **Args:**
  * `type: str = "wait"`

**Exemplo**:

```json
{
    "type": "wait",
    "wait_time_s": 2
}
```

#### `wait_for_element` <a href="#wait_for_element" id="wait_for_element"></a>

* **Descrição**: Espera o elemento carregar por um número definido de segundos.
* **Args:**
  * `type: str = "wait_for_element"`
  * `selector: dict`
    * `type: Enum["xpath", "css", "text"]`
    * `value: str`

**Exemplo:**

```json
{
    "type": "wait_for_element",
    "selector": {
        "type": "text",
        "value": "Carregar mais itens"
    },
    "timeout_s": 5
}
```

#### `fetch_resource` <a href="#fetch_resource" id="fetch_resource"></a>

{% hint style="warning" %}
A `fetch_resource` a instrução deve ser a instrução final na lista de instruções do navegador; quaisquer instruções subsequentes não serão executadas.
{% endhint %}

* **Descrição**: Busca a primeira ocorrência de um recurso Fetch/XHR correspondente ao padrão definido.
* **Args:**
  * `type: str = "fetch_resource"`
  * `filter: str(expressão RegEx)`
  * `on_error: Enum["error", "skip"]`

**Exemplo:**

```json
{
    "type": "fetch_resource",
    "filter": "/graphql/item/"
}
```

### Validação de instruções

Qualquer inconsistência em relação ao formato da instrução resultará em um `400` código de status e uma mensagem de erro correspondente.

Por exemplo, um payload como:

```json
{
    "source": "universal",
    "url": "https://www.example.com/", 
    "render": "html",
    "browser_instructions": [
        {
            "type": "unsupported-wait",
            "wait_time_s": 5
        }
    ]
}
```

Resultará em:

```json
{    
    "errors": {
        "message": "Unsupported action type `unsupported-wait`, choose from 'click,fetch_resource,input,scroll,scroll_to_bottom,wait,wait_for_element'"
    }
}
```

## Solução de problemas <a href="#status-codes" id="status-codes"></a>

### Códigos de status <a href="#status-codes" id="status-codes"></a>

Veja nossos códigos de resposta descritos [**aqui**](/products/pt-br/web-scraper-api/response-codes.md). Os códigos de status em relação à validação das instruções estão documentados [**aqui**](/products/pt-br/web-scraper-api/features/js-rendering-and-browser-control.md#instruction-validation).

### Erros e avisos

Se houver um erro ou aviso resultante de suas ações de navegação, você o encontrará no resultado sob as chaves `browser_instructions_error` ou `browser_instructions_warnings`. Por exemplo, se você tiver enviado as seguintes instruções do navegador e o esperado `xpath` não for localizado na página, o resultado incluirá um aviso.

`browser_instructions`:

```json
[
    {
        "type": "input", 
        "selector": {
            "type": "xpath",
            "value": "//input[@type='search']"
        },
        "value": "oxylabs"
    }
]
```

Resultados:

```json
{
  "results": [
    {
      "content": "<!doctype html><html>
        Conteúdo após executar as instruções      
      </html>",
      "created_at": "2023-10-11 11:35:23",
      "updated_at": "2023-10-11 11:36:08",
      "browser_instructions_warnings": [
        {
          "action_type": "click",
          "msg": "Não foi possível encontrar o tipo de seletor `xpath` com o valor `//input[@type=search]` na página."
        },
      ],
      "page": 1,
      "url": "https://example.com",
      "job_id": "7117835067442906113",
      "status_code": 200
    }
  ]
}

```

| Possíveis erros e avisos                                                                                 |
| -------------------------------------------------------------------------------------------------------- |
| Ocorreu um erro inesperado ao converter instruções do navegador em ações.                                |
| Ocorreu um erro inesperado ao executar `{action.type}` instruções do navegador.                          |
| A ação `{action.type}` atingiu o tempo limite.                                                           |
| Não foi possível encontrar o tipo de seletor `{selector.type}` com o valor `{selector.value}` na página. |


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://developers.oxylabs.io/products/pt-br/web-scraper-api/features/js-rendering-and-browser-control.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
