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 *