Desafios Técnicos na Otimização de Títulos em Marketplaces
A otimização de títulos de produtos em plataformas como a Amazon requer a análise de grandes volumes de palavras-chave, métricas de concorrência e testes contínuos. A abordagem manual é ineficiente devido à fragmentação de dados entre o Seller Central, ferramentas de análise de marca e plataformas de terceiros. A implementação de um pipeline automatizado que combina Robotic Process Automation (RPA) e algoritmos de Processamento de Linguagem Natural (NLP) permite a extração, análise semântica e aplicação de títulos otimizados em escala, eliminando a dependência de testes empíricos.
Arquitetura do Sistema de Otimização
O pipeline é estruturado em quatro módulos principais para garantir a integridade dos dados e a eficácia das alterações:
- Coleta de Dados: Extração automatizada de relatórios de termos de busca, métricas de conversão e títulos de concorrentes via web scraping.
- Análise Semântica: Aplicação de modelos NLP para avaliar a relevância contextual e a intenção de busca das palavras-chave.
- Geração de Títulos: Construção de variações baseada em regras ponderadas, cobertura de palavras-chave e limites de caracteres.
- Validação e Monitoramento: Atualização programática dos listings e rastreamento de métricas de tráfego e conversão para testes A/B.
Implementação do Pipeline de Automação
1. Coleta de Dados e Extração de Métricas
O módulo de coleta utiliza automação de navegador para autenticar no portal do vendedor, baixar relatórios de análise de marca e extrair dados de concorrentes. Os dados brutos são processados para calcular a relevância das palavras-chave utilizando a técnica TF-IDF.
import pandas as pd
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from sklearn.feature_extraction.text import TfidfVectorizer
import numpy as np
import time
import random
class AmazonDataScraper:
def __init__(self, driver):
self.driver = driver
self.wait = WebDriverWait(self.driver, 15)
def authenticate(self, username, password):
self.driver.get("https://sellercentral.amazon.com")
self.wait.until(EC.presence_of_element_located((By.ID, "ap_email"))).send_keys(username)
self.driver.find_element(By.ID, "continue").click()
self.wait.until(EC.presence_of_element_located((By.ID, "ap_password"))).send_keys(password)
self.driver.find_element(By.ID, "signInSubmit").click()
time.sleep(random.uniform(3, 6))
def calculate_keyword_relevance(self, keyword, product_text):
vectorizer = TfidfVectorizer(stop_words='english')
try:
tfidf_matrix = vectorizer.fit_transform([product_text, keyword])
feature_names = vectorizer.get_feature_names_out()
if keyword.lower() in feature_names:
idx = np.where(feature_names == keyword.lower())[0][0]
return round(float(tfidf_matrix[0, idx]), 4)
except ValueError:
pass
return 0.0
def extract_competitor_data(self, asin_list):
competitor_data = []
for asin in asin_list:
self.driver.get(f"https://www.amazon.com/dp/{asin}")
time.sleep(random.uniform(2, 5))
try:
title = self.wait.until(EC.presence_of_element_located((By.ID, "productTitle"))).text.strip()
competitor_data.append({"asin": asin, "title": title, "length": len(title)})
except Exception:
continue
return pd.DataFrame(competitor_data)
2. Motor de Análise Semântica e Geração de Títulos
Este componente avalia a qualidade dos títulos existentes e gera novas variações. A pontuação é calculada com base na cobertura de palavras-chave de alto valor, legibilidade e conformidade com os limites de caracteres da plataforma.
class TitleOptimizer:
def __init__(self, keywords_df):
self.keywords_df = keywords_df
def evaluate_coverage(self, title):
title_lower = title.lower()
high_value_kw = self.keywords_df[
(self.keywords_df['search_volume'] > 1000) &
(self.keywords_df['relevance'] > 0.7)
]
if high_value_kw.empty:
return 0.0
covered = sum(1 for kw in high_value_kw['keyword'] if kw.lower() in title_lower)
return covered / len(high_value_kw)
def compute_title_score(self, title):
coverage = self.evaluate_coverage(title)
readability = self._assess_readability(title)
length_penalty = self._length_penalty(len(title))
final_score = (coverage * 0.5) + (readability * 0.3) + (length_penalty * 0.2)
return round(final_score, 3)
def _assess_readability(self, title):
words = title.split()
if not words: return 0.0
avg_len = sum(len(w) for w in words) / len(words)
return 0.9 if avg_len < 8 else (0.6 if avg_len < 12 else 0.3)
def _length_penalty(self, length):
if 80 <= length <= 150: return 1.0
if 50 <= length < 80 or 150 < length <= 200: return 0.7
return 0.2
def generate_variants(self, product_data, top_n=3):
variants = []
sorted_kw = self.keywords_df.sort_values(by=['search_volume', 'relevance'], ascending=False)
core_keywords = sorted_kw.head(top_n)['keyword'].tolist()
base_title = f"{product_data['brand']} {' '.join(core_keywords)} {product_data['main_feature']}"
variants.append({"title": base_title[:200], "strategy": "keyword_density"})
return variants
3. Atualização Automatizada e Monitoramento de Testes A/B
Após a seleção do título otimizado, o sistema interage com a interface de gerenciamento de inventário para aplicar as alterações e configura um registro de rastreamento para monitorar o impacto nas métricas de tráfego.
class ListingManager:
def __init__(self, driver):
self.driver = driver
self.wait = WebDriverWait(self.driver, 10)
def update_title(self, asin, new_title):
search_box = self.wait.until(EC.presence_of_element_located((By.ID, "search-string")))
search_box.clear()
search_box.send_keys(asin)
self.driver.find_element(By.CSS_SELECTOR, "button.search-btn").click()
edit_link = self.wait.until(EC.element_to_be_clickable((By.XPATH, f"//tr[contains(.,'{asin}')]//a[text()='Edit']")))
edit_link.click()
title_input = self.wait.until(EC.presence_of_element_located((By.ID, "product-title")))
title_input.clear()
title_input.send_keys(new_title)
self.driver.find_element(By.ID, "save-and-finish").click()
self.wait.until(EC.presence_of_element_located((By.CLASS_NAME, "success-message")))
def setup_tracking(self, asin, old_title, new_title):
baseline_metrics = self._fetch_current_metrics(asin)
tracking_record = {
"asin": asin,
"previous_title": old_title,
"current_title": new_title,
"baseline_impressions": baseline_metrics.get("impressions", 0),
"baseline_clicks": baseline_metrics.get("clicks", 0),
"timestamp": pd.Timestamp.now()
}
self._save_tracking_record(tracking_record)
def _fetch_current_metrics(self, asin):
# Lógica para extrair métricas atuais do dashboard de relatórios
return {"impressions": 0, "clicks": 0}
def _save_tracking_record(self, record):
# Persistência dos dados de rastreamento em banco de dados ou arquivo CSV
pass
4. Geração de Relatórios de Desempenho
O módulo final consolida os dados de rastreamento, calcula as variações percentuais nas métricas de conversão e gera relatórios estruturados para análise.
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.application import MIMEApplication
import openpyxl
class PerformanceReporter:
def generate_excel_report(self, optimization_data, output_path):
wb = openpyxl.Workbook()
ws = wb.active
ws.title = "Resumo"
ws.append(["Métrica", "Valor"])
ws.append(["Total de Produtos Otimizados", len(optimization_data)])
if not optimization_data.empty and 'click_change' in optimization_data.columns:
ws.append(["Aumento Médio de Cliques", f"{optimization_data['click_change'].mean():.2%}"])
wb.save(output_path)
def dispatch_report(self, file_path, recipients):
msg = MIMEMultipart()
msg['Subject'] = "Relatório de Otimização de Títulos - Amazon"
msg['To'] = ", ".join(recipients)
body = MIMEText("Segue em anexo o relatório de desempenho das recentes otimizações de títulos.")
msg.attach(body)
with open(file_path, "rb") as f:
part = MIMEApplication(f.read(), Name="optimization_report.xlsx")
part['Content-Disposition'] = f'attachment; filename="optimization_report.xlsx"'
msg.attach(part)
# Configuração do servidor SMTP e envio
# server = smtplib.SMTP('smtp.example.com', 587)
# server.starttls()
# server.send_message(msg)
# server.quit()
O módulo de relatórios fecha o ciclo de feedback do sistema. Os dados de desempenho coletados são realimentados no banco de dados de palavras-chave, permitindo que o algoritmo de pontuação ajuste os pesos de relevância e conversão para iterações futuras, garantindo a melhoria contínua do modelo de otimização.