Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the blank-slate domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /sites/danielkossmann.com/files/wp-includes/functions.php on line 6114

Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the ultimate-addons-for-gutenberg domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /sites/danielkossmann.com/files/wp-includes/functions.php on line 6114

Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the hustle domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /sites/danielkossmann.com/files/wp-includes/functions.php on line 6114

Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the wordpress-seo domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /sites/danielkossmann.com/files/wp-includes/functions.php on line 6114
Construindo em Público: Gerador de Imagens Open Graph: Parte 1 - Daniel Kossmann

Durante vários anos tive a ideia de construir algo para automatizar imagens de mídias sociais dos meus blogs, também chamadas de imagens Open Graph, porque isso é algo que nunca gostei de fazer. A abordagem mais comum para resolver esse problema era criar uma página HTML com o conteúdo e estilos e usar um navegador sem cabeça para tirar uma captura de tela, mas isso sempre parecia muito trabalhoso e eu nunca comecei a fazer nada.

Enquanto assistia Language models on the command-line w/ Simon Willison para aprender mais sobre como usar LLM, descobri que o Simon criou uma ferramenta chamada shot-scraper para automatizar capturas de tela e que ela também poderia executar código JavaScript. Isso me deixou animado novamente com a ideia do meu projeto porque eu podia ver pela primeira vez uma maneira de implementá-lo.

Planejando a versão mínima viável

Para não travar em detalhes menores, planejei uma versão rápida da minha ideia para que eu pudesse ver algo funcionando e me ajudar a ficar animado para continuar trabalhando nisso. Esse foi meu plano inicial:

  1. Instalar a ferramenta e testá-la;
  2. Criar HTML simples e tirar uma captura de tela dele;
  3. Mudar o conteúdo da página usando o suporte a JavaScript da ferramenta e tirar uma captura de tela do resultado;
  4. Ler um arquivo CSV com conteúdo e tirar uma captura de tela para cada um deles.

Para me ajudar a focar, usei a Técnica Pomodoro e defini que ao final do primeiro Pomodoro eu deveria ter isso feito. Vamos lá?

1. Instalação

Eu segui a documentação oficial do shot-scraper e, como eu já tinha Python e algumas ferramentas instaladas no meu computador (Ubuntu 24.04), apenas digitei no meu terminal:

pipx install shot-scraper

shot-scraper install
Bash

Agora vamos criar uma pasta para o projeto e testar a ferramenta.

shot-scraper https://www.danielkossmann.com/
Bash

Vamos ver como definir uma largura e altura personalizadas com base no tamanho da imagem que uso para as imagens do meu blog e testar isso.

shot-scraper https://www.danielkossmann.com/ --width 1200 --height 630
Bash

Deu certo! Agora vamos passar para a próxima fase.

2. Teste com HTML personalizado

Criei um HTML simples chamado index.html usando Emmet no VS Code com html:5 e adicionei um título e descrição.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Documento</title>
</head>
<body>
    <h1>Conteúdo H1 Original</h1>
    <p>Conteúdo do parágrafo original.</p>
</body>
</html>
HTML

E então procurei como tirar uma captura de tela de um arquivo local e dar um nome à imagem.

shot-scraper index.html --width 1200 --height 630 -o thumbnail.png
Bash

Deu certo! Agora vamos passar para a próxima fase.

3. Mudando o conteúdo antes de tirar a captura de tela

Adicionar JavaScript ao shot-scraper é muito simples, e eu usei o ChatGPT para me ajudar a escrever um código para mudar o título, a descrição e a cor de fundo. Nesse processo, aprendi que a maneira mais fácil seria adicionar IDs no meu código para que eu pudesse mudá-los facilmente. Assim, atualizei o HTML para:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Documento</title>
    <style>
        body {
            background-color: white;
        }
    </style>
</head>
<body>
    <h1 id="header">Conteúdo H1 Original</h1>
    <p id="paragraph">Conteúdo do parágrafo original.</p>
</body>
</html>
HTML

E esse foi meu código JavaScript que testei rapidamente no console do navegador:

document.getElementById("header").innerHTML = "Daniel Kossmann";
document.getElementById("paragraph").innerHTML = "Sou um Gerente de Produto Técnico";
document.body.style.backgroundColor = "lightblue";
JavaScript

Mas para adicioná-lo na linha de comando, precisei trocar o tipo de aspas, e o resultado final foi. A adição do código ao shot-scraper ficou assim.

shot-scraper index.html --width 1200 --height 630 -o thumbnail.png --javascript "
document.getElementById('header').innerHTML = 'Daniel Kossmann';
document.getElementById('paragraph').innerHTML = 'Sou um Gerente de Produto Técnico';
document.body.style.backgroundColor = 'lightblue';
"
Bash

Funcionou!

Criar capturas de tela para uma lista de conteúdos

Como eu sei programar em Python, pedi ao ChatGPT para:

escreva um script em Python que lê um CSV com 4 valores (ID, NOME, DESCRIÇÃO, COR) e para cada um executa o seguinte script, substituindo cada uma das variáveis (dentro de {}):

shot-scraper index.html --width 1200 --height 630 -o {ID}.png --javascript "
document.getElementById('header').innerHTML = '{NAME}';
document.getElementById('paragraph').innerHTML = '{DESCRIPTION}';
document.body.style.backgroundColor = '{COLOR}';
"
Markdown

E mudei o resultado para salvar os arquivos na pasta screenshots/ para manter as coisas mais organizadas. Aqui está o código final para screenshots.py:

import csv
import os

# Função para executar o comando do shot-scraper
def run_shot_scraper(row):
    command = f"""
    shot-scraper index.html -o screenshots/{row['ID']}.png --width 800 --height 600 --javascript \"
    document.getElementById('header').innerHTML = \\"{row['NAME']}\\";
    document.getElementById('paragraph').innerHTML = \\"{row['DESCRIPTION'].replace('"', '\\"')}\\";
    document.body.style.backgroundColor = '{row['COLOR']}';
    \"
    """
    os.system(command)

# Ler o CSV e processar cada linha
def process_csv(file_path):
    with open(file_path, mode='r', newline='', encoding='utf-8') as file:
        csv_reader = csv.DictReader(file)
        for row in csv_reader:
            run_shot_scraper(row)

# Caminho para o seu arquivo CSV
csv_file_path = 'data.csv'

# Executar o script
process_csv(csv_file_path)
Python

Eu também criei o arquivo data.csv com alguns conteúdos fictícios:

ID,NAME,DESCRIPTION,COLOR
thumb1,Daniel Kossmann,Sou um Gerente de Produto Técnico,lightblue
thumb2,OpenAI GPT,Um modelo de linguagem IA avançado,lightgreen
thumb3,Python Script,Automatizando tarefas com facilidade,lightcoral
Markdown

O resultado foram as três imagens seguintes.

O tempo do Pomodoro acabou!

Próximos passos

Como próximo passo, provavelmente focarei em melhorar o design ou ver como obter os dados do meu blog para gerar as imagens com base nisso.


Meu plano é continuar documentando publicamente o que venho experimentando. Se você tiver alguma dica ou achou isso útil, por favor, deixe um comentário!

Este post foi escrito em quase 3 Pomodoros, ouvindo Duality da Neon Nox e Powernerd em loop.



Comments

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *