作为代码的弹性开放式网络爬虫
了解如何使用 GitHub Actions 管理 Elastic Open 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.
有了Elastic Open Web Crawler及其 CLI 驱动的架构,现在就可以非常直接地实现版本化爬虫配置和具有本地测试功能的 CI/CD 管道。
传统上,管理爬虫是一个手动且容易出错的过程。这涉及到直接在用户界面上编辑配置,以及克隆抓取配置、回滚、版本控制等问题。将爬虫配置视为代码可以解决这个问题,因为它提供了我们在软件开发中期待的相同优势:可重复性、可追溯性和自动化。
这种工作流程可以更轻松地将开放式网络爬虫带入您的 CI/CD 流水线,以进行回滚、备份和迁移--这些任务在使用早期的弹性爬虫(如弹性网络爬虫或应用程序搜索爬虫)时要棘手得多。
在本文中,我们将学习如何:
使用 GitHub 管理我们的抓取配置
在部署前进行本地设置以测试管道
创建一个生产设置,以便在每次向主分支推送更改时使用新设置运行网络爬虫
你可以在这里找到项目仓库。 在撰写本文时,我使用的是 Elasticsearch 9.1.3 和 Open Web Crawler 0.4.2。
准备工作
Docker 桌面
Elasticsearch 实例
可通过 SSH 访问的虚拟机(如 AWS EC2)并安装 Docker
步长
文件夹结构
履带配置
Docker-compose 文件(本地环境)
Github 操作
本地测试
部署到 prod
进行更改和重新部署
文件夹结构
本项目的文件结构如下:
├── 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 crawler履带配置
在crawler-config.yml, 下,我们将填写以下内容:
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/3这将从https://web-scraping.dev/products 抓取,这是一个产品模拟网站。我们只会抓取前三个产品页面。max_crawl_depth 设置将通过不打开其中的链接,防止爬虫发现比定义为seed_urls 的页面更多的页面。
Elasticsearchhost 和api_key 将根据我们运行脚本的环境动态填充。
Docker-compose 文件(本地环境)
对于本地docker-compose.yml, ,我们将部署爬虫和单个 Elasticsearch 集群 + Kibana,这样在部署到生产环境之前,我们就可以轻松查看爬虫结果。
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: bridge请注意爬虫是如何等待 Elasticsearch 准备好运行的。
Github 操作
现在,我们需要创建一个 GitHub Action,它将复制新设置,并在每次推送到 main 时在虚拟机中运行爬虫。这样就能确保我们始终部署有最新的配置,而无需手动进入虚拟机更新文件和运行爬虫。我们将使用 AWS EC2 作为虚拟机提供商。
第一步是将主机 (VM_HOST) 、机器用户 (VM_USER) 、SSH RSA 密钥 (VM_KEY) 、Elasticsearch 主机 (ES_HOST) 和 Elasticsearch API 密钥 (ES_API_KEY) 添加到 GitHub Action secrets 中:
这样,操作就能访问我们的服务器,将新文件复制过来并运行抓取。
现在,让我们创建.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
EOF每次我们向爬虫配置文件推送更改时,该操作都会执行以下步骤:
在 yml 配置中填入 Elasticsearch 主机和 API 密钥
将配置文件夹复制到我们的虚拟机
通过 SSH 连接到我们的虚拟机
使用我们刚从 repo 复制的配置运行抓取程序
本地测试
为了在本地测试爬虫,我们创建了一个 bash 脚本,将 Elasticsearch 主机与 Docker 中的本地主机进行填充,然后开始爬行。您可以运行./local.sh 来执行它。
#!/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 --build让我们看看 Kibana DevTools,以确认 web-crawler-index 的填充是否正确:
部署到 prod
现在,我们准备推送到主分支,这将在虚拟机中部署爬虫,并开始向无服务器 Elasticsearch 实例发送日志。
git add .
git commit -m "First commit"
git push这将触发 GitHub 操作,在虚拟机中执行部署脚本并开始抓取。
您可以访问 GitHub 仓库并访问 "操作 "选项卡,确认操作已执行:
进行更改和重新部署
您可能已经注意到,每个产品的price 都是文档正文字段的一部分。如果能将价格存储在一个单独的字段中,我们就可以根据它运行筛选器,这将是最理想的。
让我们在crawler.yml 文件中添加这一更改,使用提取规则从product-price CSS 类中提取价格:
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: html我们还可以看到,价格包含一个美元符号 ($),如果要运行范围查询,我们必须去掉这个符号。为此,我们可以使用摄取管道。请注意,我们在上面的新爬虫配置文件中引用了它:
PUT _ingest/pipeline/pricing-pipeline
{
"processors": [
{
"script": {
"source": """
ctx['price'] = ctx['price'].replace("$","")
"""
}
}
]
}我们可以在生产 Elasticsearch 集群中运行该命令。对于开发进程,由于它是短暂的,我们可以通过添加以下服务,使管道创建成为docker-compose.yml 文件的一部分。请注意,我们还为爬虫服务添加了一个depends_on ,这样它就能在管道创建成功后启动。
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!';
"现在让我们运行`./local.sh` 查看本地的变化:
太好了!现在让我们推动变革:
git add crawler-config.yml
git commit -m "added price CSS selector"
git push要确认一切正常,可以检查生产的 Kibana,它应该会反映这些更改,并将价格显示为一个不带美元符号的新字段。
结论
Elastic Open Web Crawler 允许您将爬虫作为代码进行管理,这意味着您可以自动执行从开发到部署的整个流程,并以编程方式添加短暂的本地环境和针对爬虫数据的测试。
我们邀请您克隆官方资源库,并开始使用此工作流程为自己的数据编制索引。您还可以阅读本文,了解如何在爬虫生成的索引上运行语义搜索。




