Elastic Open Web Crawler como código
Aprenda a usar o GitHub Actions para gerenciar as configurações do Elastic Open Crawler, de forma que, sempre que enviarmos alterações para o repositório, elas sejam aplicadas automaticamente à instância implantada do crawler.
Check out the different ways to ingest data into Elasticsearch and dive into practical examples to try something new.
Elasticsearch is packed with new features to help you build the best search solutions for your use case. Start a free cloud trial or try Elastic on your local machine now.
Com o Elastic Open Web Crawler e sua arquitetura orientada por linha de comando, ter configurações de crawler versionadas e um pipeline de CI/CD com testes locais agora é bastante simples de se obter.
Tradicionalmente, o gerenciamento de rastreadores era um processo manual e propenso a erros. Isso envolvia editar configurações diretamente na interface do usuário e ter dificuldades com a clonagem de configurações de rastreamento, reversão, controle de versão e muito mais. Tratar as configurações do rastreador como código resolve isso, proporcionando os mesmos benefícios que esperamos no desenvolvimento de software: repetibilidade, rastreabilidade e automação.
Esse fluxo de trabalho facilita a integração do Open Web Crawler ao seu pipeline de CI/CD para reversões, backups e migrações — tarefas que eram muito mais complicadas com versões anteriores do Elastic Crawler, como o Elastic Web Crawler ou o App Search Crawler.
Neste artigo, vamos aprender como:
Gerencie nossas configurações de rastreamento usando o GitHub.
Ter um ambiente local para testar pipelines antes da implantação.
Criar um ambiente de produção para executar o rastreador web com novas configurações sempre que enviarmos alterações para nossa branch principal.
Você pode encontrar o repositório do projeto aqui. No momento em que escrevo, estou usando o Elasticsearch 9.1.3 e o Open Web Crawler 0.4.2.
Pré-requisitos
Docker Desktop
instância do Elasticsearch
Máquina virtual com acesso SSH (por exemplo, AWS EC2) e Docker instalado.
Etapas
Estrutura de pastas
Configuração do rastreador
Arquivo Docker-compose (ambiente local)
Ações do GitHub
Testando localmente
Implantação em produção
Realizar alterações e redistribuir
Estrutura de pastas
Para este projeto, teremos a seguinte estrutura de arquivos:
├── docker-compose.yml # Local elasticsearch + crawler
├── config/crawler-config.yml # Crawler config
├── .github/workflows/deploy.yml # GH Action to deploy changes
├── local.sh # Script to run our local crawlerConfiguração do rastreador
Em crawler-config.yml, colocaremos o seguinte:
output_sink: elasticsearch
output_index: web-crawl-index
max_crawl_depth: 1
elasticsearch:
host: ${ES_HOST}
api_key: ${ES_API_KEY}
domains:
- url: https://web-scraping.dev
seed_urls:
- https://web-scraping.dev/product/1
- https://web-scraping.dev/product/2
- https://web-scraping.dev/product/3Este script irá extrair dados de https://web-scraping.dev/products, um site fictício para produtos. Iremos rastrear apenas as três primeiras páginas de produtos. A configuração max_crawl_depth impedirá que o rastreador descubra mais páginas do que as definidas como seed_urls , não abrindo os links dentro delas.
Elasticsearch host e api_key serão preenchidos dinamicamente dependendo do ambiente em que estamos executando o script.
Arquivo Docker-compose (ambiente local)
Para o ambiente local docker-compose.yml, implantaremos o rastreador e um único cluster Elasticsearch + Kibana, para que possamos visualizar facilmente os resultados do rastreamento antes da implantação em produção.
services:
es01:
image: docker.elastic.co/elasticsearch/elasticsearch:9.1.3
environment:
- discovery.type=single-node
- xpack.security.enabled=false
- ES_JAVA_OPTS=-Xms1g -Xmx1g
ports:
- "9200:9200"
networks: [esnet]
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9200"]
interval: 5s
timeout: 5s
retries: 10
kibana:
image: docker.elastic.co/kibana/kibana:9.1.3
environment:
- ELASTICSEARCH_HOSTS=http://es01:9200
ports:
- "5601:5601"
networks: [esnet]
depends_on: [es01]
crawler:
image: docker.elastic.co/integrations/crawler:0.4.2
environment:
- ES_HOST=http://es01:9200
- CRAWLER_JRUBY_OPTS=--server
container_name: crawler
volumes:
- ./config:/home/app/config
networks: [esnet]
entrypoint: ["/home/app/bin/crawler", "crawl", "/home/app/config/crawl-config-final.yml"]
stdin_open: true
tty: true
networks:
esnet:
driver: bridgeObserve como o rastreador aguarda até que o Elasticsearch esteja pronto para ser executado.
Ações do GitHub
Agora precisamos criar uma ação do GitHub que copie as novas configurações e execute o rastreador em nossa máquina virtual a cada push para o repositório principal. Isso garante que sempre tenhamos a configuração mais recente implantada, sem precisar entrar manualmente na máquina virtual para atualizar arquivos e executar o rastreador. Vamos usar o AWS EC2 como provedor de máquinas virtuais.
O primeiro passo é adicionar o host (VM_HOST), o usuário da máquina (VM_USER), a chave SSH RSA (VM_KEY), o host do Elasticsearch (ES_HOST) e a chave da API do Elasticsearch (ES_API_KEY) aos segredos da ação do GitHub:
Dessa forma, a ação poderá acessar nosso servidor para copiar os novos arquivos e executar a indexação.
Agora, vamos criar nosso arquivo .github/workflows/deploy.yml :
name: Deploy
on:
push:
branches: [main]
jobs:
Deploy:
name: Deploy to EC2
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Deploy crawler
env:
HOSTNAME: ${{ secrets.VM_HOST }}
USER_NAME: ${{ secrets.VM_USER }}
PRIVATE_KEY: ${{ secrets.VM_KEY }}
ES_HOST: ${{ secrets.ES_HOST }}
ES_API_KEY: ${{ secrets.ES_API_KEY }}
run: |
# Save private key
echo "$PRIVATE_KEY" > private_key
chmod 600 private_key
# Generate final config locally
envsubst < config/crawler-config.yml > config/crawl-config-final.yml
# Copy the config folder to VM
scp -o StrictHostKeyChecking=no -i private_key -r config ${USER_NAME}@${HOSTNAME}:~/config
# SSH into VM and run crawler
ssh -o StrictHostKeyChecking=no -i private_key ${USER_NAME}@${HOSTNAME} << EOF
docker run --rm \
-v ~/config:/config \
docker.elastic.co/integrations/crawler:latest jruby \
bin/crawler crawl /config/crawl-config-final.yml
EOFEssa ação executará os seguintes passos sempre que enviarmos alterações para o arquivo de configuração do rastreador:
Preencha o arquivo de configuração YAML com o host e a chave da API do Elasticsearch.
Copie a pasta de configuração para a nossa máquina virtual.
Conecte-se à nossa VM via SSH.
Execute o rastreamento com a configuração que acabamos de copiar do repositório.
Testando localmente
Para testar nosso rastreador localmente, criamos um script bash que popula o host do Elasticsearch com a versão local do Docker e inicia uma busca. Você pode executar ./local.sh para executá-lo.
#!/bin/bash
# Exit on any error
set -e
# Load environment variables
export ES_HOST="http://es01:9200"
# Generate final crawler config
envsubst < ./config/crawler-config.yml > ./config/crawl-config-final.yml
# Bring everything up
docker compose up --buildVamos verificar as Ferramentas de Desenvolvedor do Kibana para confirmar se o campo web-crawler-index foi preenchido corretamente:
Implantação em produção
Agora estamos prontos para enviar a alteração para a branch principal, o que implantará o crawler em sua máquina virtual e começará a enviar logs para sua instância do Elasticsearch Serverless.
git add .
git commit -m "First commit"
git pushIsso acionará a ação do GitHub, que executará o script de implantação na máquina virtual e iniciará a indexação.
Você pode confirmar se a ação foi executada acessando o repositório do GitHub e visitando a aba “Ações”:
Realizar alterações e redistribuir
Algo que você pode ter notado é que o price de cada produto faz parte do corpo do documento. O ideal seria armazenar o preço em um campo separado para que pudéssemos aplicar filtros a ele.
Vamos adicionar essa alteração ao arquivo crawler.yml para usar regras de extração para extrair o preço da classe CSS product-price :
output_sink: elasticsearch
output_index: web-crawl-index
max_crawl_depth: 1
elasticsearch:
host: ${ES_HOST}
api_key: ${ES_API_KEY}
# Index ingest pipeline to process documents before indexing
pipeline_enabled: true
pipeline: pricing-pipeline
domains:
- url: https://web-scraping.dev
seed_urls:
- https://web-scraping.dev/product/1
- https://web-scraping.dev/product/2
- https://web-scraping.dev/product/3
extraction_rulesets:
- url_filters:
- type: ends
pattern: /product/*
rules:
- action: extract
field_name: price
selector: .product-price
join_as: string
source: htmlTambém vemos que o preço inclui um sinal de dólar ($), que devemos remover se quisermos executar consultas de intervalo. Podemos usar um pipeline de ingestão para isso. Observe que estamos fazendo referência a ele em nosso novo arquivo de configuração do rastreador acima:
PUT _ingest/pipeline/pricing-pipeline
{
"processors": [
{
"script": {
"source": """
ctx['price'] = ctx['price'].replace("$","")
"""
}
}
]
}Podemos executar esse comando em nosso cluster Elasticsearch de produção. Para o desenvolvimento, como é efêmero, podemos fazer com que a criação do pipeline faça parte do arquivo docker-compose.yml adicionando o seguinte serviço. Observe que também adicionamos um depends_on ao serviço de rastreamento para que ele seja iniciado após a criação bem-sucedida do pipeline.
crawler:
image: docker.elastic.co/integrations/crawler:0.4.2
environment:
- ES_HOST=http://es01:9200
- CRAWLER_JRUBY_OPTS=--server
container_name: crawler
volumes:
- ./config:/home/app/config
networks: [esnet]
entrypoint: ["/home/app/bin/crawler", "crawl", "/home/app/config/crawl-config-final.yml"]
depends_on:
pipeline-init:
condition: service_completed_successfully
stdin_open: true
tty: true
pipeline-init:
image: curlimages/curl:latest
depends_on:
es01:
condition: service_healthy
networks: [esnet]
entrypoint: >
sh -c "
echo 'Creating ingest pipeline...';
curl -s -X PUT http://es01:9200/_ingest/pipeline/pricing-pipeline \\
-H 'Content-Type: application/json' \\
-d '{\"processors\":[{\"script\":{\"source\":\"ctx.price = ctx.price.replace(\\\"$\\\", \\\"\\\")\"}}]}';
echo 'Pipeline created!';
"Agora vamos executar `./local.sh` para ver a alteração localmente:
Ótimo! Agora vamos impulsionar a mudança:
git add crawler-config.yml
git commit -m "added price CSS selector"
git pushPara confirmar se tudo funciona corretamente, você pode verificar seu Kibana de produção, que deverá refletir as alterações e mostrar o preço como um novo campo sem o símbolo de dólar.
Conclusão
O Elastic Open Web Crawler permite que você gerencie seu crawler como código, o que significa que você pode automatizar todo o pipeline — do desenvolvimento à implantação — e adicionar ambientes locais efêmeros e testes com os dados rastreados programaticamente, para citar alguns exemplos.
Você está convidado a clonar o repositório oficial e começar a indexar seus próprios dados usando este fluxo de trabalho. Você também pode ler este artigo para aprender como executar uma pesquisa semântica em índices produzidos pelo rastreador.




