Google Sheets · Apps Script · Zalando · Otto
Leve dados de produtos da Zalando e da Otto para o Google Sheets
Muitas verificações de preço começam em uma planilha: uma lista de produtos, o preço de hoje, o preço da semana passada. Copiar esses números à mão da Zalando ou da Otto cansa rápido. O Google Sheets tem uma ferramenta de scripts integrada, o Apps Script, que consegue buscar dados da web – assim a planilha se preenche sozinha.
Neste guia, você adiciona um pequeno script a uma planilha do Google. Um botão atualiza título, marca, preço e disponibilidade de uma lista de links de produtos da Zalando; outro preenche uma segunda aba com os resultados de busca da Otto para um termo. Um timer diário mantém os preços atualizados. Tudo roda dentro do Google – você não precisa de servidor nem de um computador ligado o tempo todo.
Atualizado em · por everydata.io
O que você terá no final
- Uma aba “Zalando” que atualiza preços e disponibilidade dos seus links de produtos.
- Uma aba “Otto” que lista a primeira página de resultados de busca para qualquer termo.
- Um menu everydata na planilha e uma atualização diária opcional.
O que você precisa
- Uma conta do Google e uma nova planilha no Google Sheets.
- Uma chave de API gratuita da everydata.io – crie uma aqui.
- Alguns links de produtos da Zalando (por exemplo, da zalando.de) e um termo de busca para a Otto.
01Prepare as duas abas
- Renomeie a primeira aba para
Zalando. Coloque estes cabeçalhos na linha 1: URL, Título, Marca, Preço, Preço normal, Disponibilidade, Verificado em. Cole seus links de produtos da Zalando na coluna A a partir da linha 2. - Adicione uma segunda aba chamada
Otto. Escreva “Termo de busca” em A1 e o seu termo (por exemplo, “highboard”) em B1. Coloque os cabeçalhos Produto, Marca, Preço, Preço normal, Nota, Link na linha 3.
02Guarde sua chave de API no script, não em uma célula
Abra Extensões → Apps Script. No editor, vá em Configurações do projeto → Propriedades do script e adicione uma propriedade chamada EVERYDATA_API_KEY com sua chave como valor. Quem tiver acesso à planilha vê as células, mas não as propriedades do script.
03Cole o script
Substitua o conteúdo de Code.gs pelo script abaixo e salve. refreshZalando envia cada link de produto ao endpoint da Zalando e escreve o resultado ao lado. searchOtto envia o termo de busca ao endpoint de busca da Otto e escreve uma linha por produto.
const API = "https://api.everydata.io";
/**
* One GET request to everydata.io. The key lives in the script properties, not in the sheet.
* Waits when rate limited (429) and retries a failed page load (5xx) once; other errors come back as { error }.
*/
function apiGet(path, params) {
const key = PropertiesService.getScriptProperties().getProperty("EVERYDATA_API_KEY");
const query = Object.keys(params)
.map((k) => encodeURIComponent(k) + "=" + encodeURIComponent(params[k]))
.join("&");
let retried = false;
for (let attempt = 0; attempt < 4; attempt++) {
const res = UrlFetchApp.fetch(API + path + "?" + query, {
headers: { "x-api-key": key },
muteHttpExceptions: true,
});
const code = res.getResponseCode();
if (code === 429) {
// Too many requests at once. The answer says how long to wait: "... Try again in 12 seconds."
const wait = res.getContentText().match(/in (\d+) seconds/);
Utilities.sleep(Math.min(wait ? Number(wait[1]) + 1 : 60, 60) * 1000);
continue;
}
if (code >= 500 && !retried) {
retried = true; // 5xx answers are not counted against your quota
Utilities.sleep(5000);
continue;
}
if (code >= 400) return { error: code };
return JSON.parse(res.getContentText());
}
return { error: 429 };
}
/** Sheet "Zalando": product URLs in column A from row 2; writes columns B–G. */
function refreshZalando() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Zalando");
const lastRow = sheet.getLastRow();
if (lastRow < 2) return;
const urls = sheet.getRange(2, 1, lastRow - 1, 1).getValues();
const rows = urls.map(([url]) => {
if (!url) return ["", "", "", "", "", ""];
const p = apiGet("/zal/zalando-lookup-product", { url: url });
if (p.error) return ["Error " + p.error, "", "", "", "", new Date()];
return [p.productTitle, p.manufacturer, p.price, p.retailPrice, p.warehouseAvailability, new Date()];
});
sheet.getRange(2, 2, rows.length, 6).setValues(rows);
}
/** Sheet "Otto": search term in B1; writes the first page of results from row 4. */
function searchOtto() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Otto");
const keyword = sheet.getRange("B1").getValue();
const data = apiGet("/ott/otto-search-by-keyword", { keyword: keyword, page: 1 });
if (sheet.getLastRow() >= 4) sheet.getRange(4, 1, sheet.getLastRow() - 3, 6).clearContent();
if (data.error) {
sheet.getRange("A4").setValue("Error " + data.error);
return;
}
const rows = (data.searchProductDetails || []).map((p) => [
p.productDescription, p.manufacturer, p.price, p.retailPrice, p.productRating, "https://www.otto.de" + p.dpUrl,
]);
if (rows.length) sheet.getRange(4, 1, rows.length, 6).setValues(rows);
}
/** Adds an "everydata" menu to the spreadsheet. */
function onOpen() {
SpreadsheetApp.getUi()
.createMenu("everydata")
.addItem("Refresh Zalando prices", "refreshZalando")
.addItem("Search Otto", "searchOtto")
.addToUi();
}Recarregue a planilha: aparece um menu “everydata”. Na primeira vez que você o usar, o Google pede permissão para o script se conectar a um serviço externo – essa é a requisição à everydata.io.
04O que volta
Para um link de produto da Zalando, a API devolve a página de produto atual em forma de dados. Exemplo documentado, resumido:
{
"responseStatus": "PRODUCT_FOUND_RESPONSE",
"responseMessage": "Product successfully found!",
"productTitle": "EVERQUEST TEXAPORE MID - Hikingschuh - dusty olive",
"manufacturer": "Jack Wolfskin",
"url": "https://www.zalando.de/jack-wolfskin-everquest-texapore-mid-hikingschuh-dusty-olive-ja442c00s-n11.html",
"warehouseAvailability": "Auf Lager.",
"retailPrice": 119.95,
"price": 104.97,
"priceSaving": 14.98
}price é quanto o produto custa agora; retailPrice, o preço normal antes do desconto. Em uma busca na Otto, cada produto em searchProductDetails vira uma linha. dpUrl é um caminho no otto.de, por isso o script coloca https://www.otto.de na frente:
{
"responseStatus": "PRODUCT_FOUND_RESPONSE",
"responseMessage": "Product successfully found!",
"keyword": "highboard",
"resultCount": 5166,
"searchProductDetails": [
{
"productDescription": "LeGer Home by Lena Gercke Highboard Essentials, Sideboard, Kommode, Anrichte, Schrank, Stauraumschrank, Breite: 111 cm, UV lackiert, Push-to-open-Funktion",
"manufacturer": "LeGer Home by Lena Gercke",
"price": 869.99,
"retailPrice": 1109.99,
"productRating": "1.0",
"dpUrl": "/p/leger-home-by-lena-gercke-highboard-essentials-sideboard-kommode-anrichte-schrank-stauraumschrank-breite-111-cm-uv-lackiert-push-to-open-funktion-1658198337/?variationId=2081559634"
}
]
}05Atualize os preços todos os dias
Adicione esta função ao mesmo script, selecione-a na barra de ferramentas do editor e clique em Executar uma vez. A partir daí, o Google atualiza a aba da Zalando toda manhã, mesmo com a planilha fechada.
/** Run once from the editor: refreshes the Zalando sheet every morning between 7 and 8. */
function installDailyTrigger() {
ScriptApp.newTrigger("refreshZalando").timeBased().everyDays(1).atHour(7).create();
}Para manter um histórico em vez de sobrescrever os preços, copie a coluna Preço para uma nova coluna (ou uma segunda aba) antes de cada atualização.
06Quantas requisições isso consome
Cada consulta de produto da Zalando conta como 2 requisições na sua cota mensal; uma busca na Otto conta como 1. Por exemplo, a atualização diária de um produto da Zalando dá cerca de 60 requisições por mês, então o plano gratuito de 100 requisições basta para testar. Para listas maiores, veja os preços.
Evite chamar a API a partir de uma fórmula personalizada de célula, como =ZALANDO(A2). O Sheets recalcula fórmulas no próprio ritmo, o que pode repetir requisições que você não pretendia fazer. Um item de menu ou um timer roda exatamente quando você decide.
Endpoints usados neste guia
Product details by URL · API Zalando
Search products by keyword · API Otto
O que mais você pode fazer com esses dados
Qualquer página de produto do zalando.de ou .co.uk em JSON: título, marca, vendedor, preço, desconto, imagens, materiais e cada tamanho e cor com estoque.
Qualquer página de produto do otto.de em JSON: título, fabricante, price, retailPrice, priceSaving, estoque, imagens, especificações e todas as variações.
Teste com seus próprios dados
O plano gratuito inclui 100 requisições por mês, válidas em todas as plataformas – o suficiente para seguir este guia do início ao fim.