Pular para o conteúdo

Dados de backlinks em JSON: $100 de crédito grátis, sem cartão, login com Google.

SEOMasters.dev
SEOMasters.devCadastre-se

Navegue por um verificador de backlinks por URL sem lacunas ou loops infinitos

Linhas por chamada, páginas por consulta e um teto rígido em 50.000. Aqui está um loop que respeita todos os três e indica quando parar.

Arcos de ponte de pedra sem fim atravessando um rio nebuloso sem lacunas
Os três números para lembrar

Até 1.000 linhas são retornadas por chamada. Cada chamada é cobrada uma vez, independentemente do número de linhas. A paginação profunda é limitada a 50.000 linhas, o que equivale a 50 chamadas de 1.000 linhas cada.

Por que a ordenação vem antes da paginação

Paginar sobre uma lista não ordenada é como aparecem duplicatas. Envie sempre sort e order junto com page e per, para que a página 3 signifique a mesma coisa em todas as solicitações da execução.

Uma consulta refdomains custa 2 créditos por chamada, então 50 chamadas totalizam 100 créditos, ou um centavo. Mesmo no pior caso, o custo é baixo; o verdadeiro custo é um loop que não termina.

Escolhendo a coluna de ordenação

A coluna pela qual ordenar depende da pergunta. A ordem decrescente é a escolha usual para auditorias, pois o teto corta a cauda longa em vez da parte que realmente importa.

Ordene por um campo que não tenha significado para a sua pergunta, e o corte pode remover as linhas que você queria. Puxe dez linhas por cada ordenação candidata e veja qual fatia sobrevive ao limite.

Registre a escolha no relatório, para que a próxima pessoa saiba por que o corte caiu onde caiu.

Registros que se movem durante uma execução

Os dados não se movem durante uma execução, a menos que a reconstrução mensal ocorra no meio dela. Raro, mas real. Um trabalho noturno que abrange o primeiro do mês pode retornar uma página do índice antigo e a próxima do índice novo, então registre o horário de início no seu log e compare.

Registre o horário de início no topo do log e o número da página em cada linha. Assim, uma inconsistência no output aponta para timing, não para um bug de parsing.

Se o job estiver agendado, evite um horário de início logo antes de uma reconstrução provável. Seus logs mostram uma reconstrução como uma mudança nos totais entre duas execuções que, caso contrário, coincidem, então mantenha os totais em cada linha do log.

Uma execução que abrange uma reconstrução não está errada por padrão. Ela é apenas inconsistente, então marque essas execuções no log e refaça a fatia afetada quando for relevante para um relatório.

Um loop de paginação que para

TypeScript para um worker Node 20. Ele para na primeira página curta, no limite ou em qualquer ok que não seja verdadeiro.

ts
const BASE = "https://seomasters.dev/api.php";
const CAP = 50_000;
const PER = 1000;

export async function pullAll(domain: string, key: string) {
  const rows: unknown[] = [];
  for (let page = 1; rows.length < CAP; page++) {
    const u = new URL(BASE);
    u.search = new URLSearchParams({
      action: "refdomains", q: domain,
      page: String(page), per: String(PER),
      sort: "dr", order: "desc",
    }).toString();
    const res = await fetch(u, { headers: { Authorization: `Bearer ${key}` } });
    if (res.status === 401 || res.status === 402) throw new Error(`stop: HTTP ${res.status}`);
    const body = await res.json();
    if (!body.ok) throw new Error(JSON.stringify(body).slice(0, 300));
    const chunk = findRows(body);   // see note below
    rows.push(...chunk);
    if (chunk.length < PER) break;  // short page means we are done
  }
  return rows;
}

Solução de problemas em uma execução de paginação

O que você vêProvável motivoO que fazer
A página 51 retorna vazia ou com erroVocê atingiu o limite de 50.000Restrinja com outra ação ou uma sort diferente, depois mescle por id
Mesmo domínio em duas páginasConsulta não ordenada ou reconstrução do índice durante a execuçãoEnvie sort e order; remova duplicatas na chave de domínio
Menos linhas do que o total do dashboardO total é para todo o grafo, a consulta tem limiteMostre "top 50.000" na UI
Loop nunca terminaVerificação de condição usa apenas rows.lengthQuebre em uma página curta, como acima
Fatura maior do que o esperadoTentativa em todos os não-200Tentativa apenas em falhas de rede, veja errors
Jardineiro inspecionando mudas únicas em uma estufa iluminada pelo sol

Lendo linhas sem adivinhar nomes de campos

O helper findRows acima é deixado intencionalmente aberto. Faça uma chamada real, olhe o JSON e escreva o acessor com base no que você vê, e não no que um tutorial prometeu.

Para o primo mais barato deste job, pontuando muitos domínios de uma vez sem paginação, leia o bulk DR script.

Congele uma resposta como fixture

Então congule-a com um teste. Salve uma resposta como um arquivo fixture e faça assertions sobre a contagem de linhas e as chaves da primeira linha, para que uma mudança futura falhe no CI e não no gráfico de um cliente.

Mantenha o fixture no controle de versão junto ao teste, para que um revisor veja a estrutura que o código espera sem precisar executar nada.

Quando a API adicionar um campo mais tarde, o diff do fixture dirá se o seu acessor notou ou ignorou silenciosamente.

Nomeie o fixture com base na consulta de onde ele veio, como a ação, o domínio e a ordenação. Um arquivo chamado response1.json não diz nada ao próximo leitor sobre o que ele comprova.

Conte as linhas que você armazenou

Compare as linhas que você salvou com o total relatado pelo loop. Uma lacuna significa que uma página foi perdida, e uma repetição significa que uma página foi buscada duas vezes e upsertada em uma única linha.

Execute essa verificação após cada pull de teste, não apenas após o primeiro. Desvios na contagem são geralmente o primeiro sintoma de uma ordenação alterada ou de uma reconstrução ocorrendo no meio da execução.

Mantenha a contagem na mesma linha do log que o número da página, para que os dois possam ser lidos juntos de relance.

Dividindo o trabalho acima do limite

Algumas perguntas superam o limite. Para listas acima do teto, divida o problema em vez de paginar mais. Puxe os top 50.000 por uma ordenação, depois pergunte a outras ações sobre os heavy hitters, já que esses também custam 2 créditos e respondem a perguntas diferentes. Paginar mais nunca ultrapassa o corte.

Puxe os top 50.000 por uma ordenação

Aceite o limite como um fato da API. Puxe os top 50.000 linhas por uma ordenação, armazene-os e rotule o resultado como a fatia superior em qualquer relatório.

Um dashboard que mostra uma contagem limitada como se fosse o total total engana as pessoas que o leem. O rótulo não custa nada, e um relatório de url backlink checker lê-se mais honestamente com ele.

Decida o tamanho da fatiga antes da execução e escreva no cabeçalho do relatório, para que o número nunca pareça maior do que é. Uma linha de cabeçalho não custa nada, e um leitor que encontrar uma linha faltando depois agradecerá por isso.

Faça uma pergunta diferente aos heavy hitters

anchors e toppages respondem a outras perguntas, como qual anchor text domina ou quais páginas atraem os links. Para um domínio além do limite, essas respostas podem ser mais importantes do que a próxima página da mesma lista.

Mantenha os resultados deles em suas próprias tabelas, chaves pelo domínio, para que uma consulta posterior do mesmo domínio possa substituí-los sem tocar nas linhas da fatia superior.

Cada ação extra custa seus próprios créditos, então precifique antes da execução, não depois que a fatura chegar.

Uma lista curta dos domínios mais pesados, puxada uma vez por mês, frequentemente dá mais contexto útil do que uma lista maior puxada todas as noites.

Mesclando na chave de domínio

Quando duas consultas se sobrepõem, mescle-as na chave de domínio e mantenha o timestamp mais recente. A mesclagem então nunca depende de qual consulta terminou primeiro.

Registre qual consulta venceu em cada linha. Se um número mudar entre dois relatórios, esse log dirá se foi o índice ou a mesclagem que mudou.

Mantenha a mesclagem em uma única função com um teste, já que é o único lugar onde duas consultas se encontram.

Retomando após uma falha

Falhas acontecem. Uma implantação reinicia o worker, um laptop entra em suspensão, uma VPN cai e o loop morre na página 31 de 50.

Salve a página após cada chamada

Persista o último número de página concluído após cada chamada. Reinicie a partir desse número mais um, e não do início, e você pagará por 2 créditos por página em vez de recomprar toda a consulta.

Salve-o após o parsing da resposta, não antes. Uma página que você falhou em ler deve ser buscada novamente, e um número de página salvo deve sempre significar linhas que você possui.

Uma gravação que ocorre uma vez por minuto em vez de uma vez por chamada deixa uma janela onde uma falha pode repetir o gasto de créditos. Mantenha a escrita pequena, para que seja barata fazer cada vez.

Registre quanto tempo cada gravação leva, assim como quanto tempo cada chamada leva. Uma gravação que rivaliza com a chamada aponta para a camada de armazenamento, e isso vale a pena corrigir antes que o loop cresça.

Upsert na chave de domínio

Mantenha uma escrita idempotente. Upsert cada linha na sua chave de domínio, para que uma página buscada duas vezes deixe uma linha, não duas.

Use a mesma chave em todos os caminhos de escrita, incluindo o script de reparo manual. Dois caminhos de escrita com duas chaves são como as duplicatas sobrevivem a uma retomada.

Um script de reparo é frequentemente escrito às pressas, após uma execução falhada. É quando uma segunda chave se infiltra, então revise-o com tanto cuidado quanto o loop principal.

Rejeite uma retomada quando a ordenação mudar

Registre a ordenação e a ordem junto com o número da página. Se alguém alterar sort entre uma falha e o reinício, o número de página salvo não mais significa a mesma fatia. Rejeite a retomada e comece do zero.

Armazene um pequeno registro de retomada com a ordenação, a ordem, a página e o horário. O loop lê esse registro primeiro, e ele se recusa a continuar se qualquer campo não corresponder mais à solicitação que está prestes a fazer.

Uma retomada rejeitada não é uma falha. É o loop dizendo que a página salva não mais significa as mesmas linhas, e começar do zero é o erro mais barato.

Executando o loop em produção

  1. 1

    Comece com um domínio pequeno

    Execute o loop contra um domínio com algumas centenas de linhas, para que o stop de página curta dispare e você veja o caminho de saída funcionando.

  2. 2

    Verifique uma página a olho nu

    Abra uma resposta armazenada e confirme que o acessor ainda lê as linhas. Não confie em um parse que você não olhou.

  3. 3

    Mantenha os limites na configuração

    Coloque o limite e o tamanho da página em um arquivo de configuração, para que uma mudança apareça na revisão e não se esconda dentro de uma função.

  4. 4

    Registre o motivo pelo qual o loop terminou

    Registre se a execução terminou em uma página curta, no limite ou em um erro. Essas três finalidades significam coisas diferentes para quem lê o log.