iT邦幫忙

2022 iThome 鐵人賽

DAY 17
0
DevOps

其實沒有那麼難 — Docker系列 第 17

D17 - 團隊觀戰區爬蟲 v3 ft. AWS S3

  • 分享至 

  • xImage
  •  

今天再次來改良團隊觀戰區爬蟲,

想要把爬蟲的結果放到 AWS S3 上,改成用 S3 檔案的形式提供 API
Let's go!


改良的目的

在上一次的 團隊觀戰區爬蟲 v2 中,我們提供了團隊參賽資訊的 API,然後還有幾個問題要處理:

  1. 我沒有買網域,因此沒有 HTTPS
  2. API 的結果變化不快,沒必要呼叫都爬

因此,我想要把爬蟲的結果放到 S3 上面,建立檔案,
這樣能夠帶來三個好處:

  1. S3 可以直接提供擁有 HTTPS 的連結
  2. 不需要每次被呼叫 API 就爬一次資料
  3. 把流量的壓力轉移到 S3

AWS S3

S3 是 Simple Storage Service 的縮寫,是 AWS 用來放檔案的服務,

同時 AWS 提供了多種語言的 SDK,也包含了 JavaScript,因此要串接 AWS 已經相對容易很多了,

一個 S3 Bucket 相當於一個主資料夾,當我把一個 Bucket 設定為能公開讀取,並且存成 JSON 檔,就能讓使用者像使用 API 一樣地呼叫了,

今天比賽社群上有人 (或官方) 也做了一個 鐵人賽觀戰區,是以個人為單位來查看的,
可以注意到他們也是用這種方式提供 API 的,


爬蟲程式碼

補點字數 來講解一點程式碼吧,

.env

記得要設定 .env:

AWS_ACCESS_KEY_ID=<KEY_ID>
AWS_SECRET_ACCESS_KEY=<ACCESS_KEY>
AWS_DEFAULT_REGION=ap-northeast-1
AWS_BUCKET=ithome-ironman-team-watcher

上傳 S3

import { PutObjectCommand, S3Client } from '@aws-sdk/client-s3';

const s3Client = new S3Client({
	region: process.env.AWS_DEFAULT_REGION
});

async function uploadTeamData(teamId, data) {
	const params = {
		Bucket: process.env.AWS_BUCKET,
		Key: `2022/team-${teamId}.json`,
		Body: JSON.stringify(data),
		ContentType: 'application/json',
	};
    // AWS SDK 會自動讀取環境變數中的 Access Key
	await s3Client.send(new PutObjectCommand(params));
}

爬蟲程式

export async function keepUploadingTeamData() {
	const minutes = 5;

	console.log(`keep to upload data of ithelp teams for every ${minutes} minutes`);

	crawlAndUploadTeamData(teamIds);
	setInterval(async () => {
		await crawlAndUploadTeamData(teamIds);
	}, minutes * 60 * 1000);
}

async function crawlAndUploadTeamData(teamIds) {
	console.log(`Start to crawl teams: `, teamIds);
	const promises = teamIds.map(async (teamId) => {
		try {
			const members = await getMembersWithPostInfo(teamId);
			console.log(`Start to upload data of members for team ${teamId}`);
			await uploadTeamData(teamId, { data: members });
			console.log(`Uploaded, team: ${teamId}`);
		} catch (error) {
			console.error(`error: crawlAndUploadAllTeamData: teamId: ${teamId}`, error);
		}
	});
	await Promise.all(promises);
	console.log(`All team finished`);
}

成果

目前設定每五分鐘就執行一次爬蟲,並上傳到 S3,
讓我們用 Docker Compose 來跑起來:

# docker-compose.yml

version: '3'
services:
  ithelp-team-crawler-s3:
    build: .
    image: 'ithelp-team-crawler-s3'
    restart: unless-stopped
    env_file:
      - .env
$ sudo docker compose up -d

S3

這裡也送上我們團隊的參賽資訊:

https://ithome-ironman-team-watcher.s3.ap-northeast-1.amazonaws.com/2022/team-249.json

如果讀者也是還沒完賽的團隊,也可以把團隊 ID 改掉,換成你們的 ID,就可以看到你們目前的參賽資訊,
e.g. https://ithome-ironman-team-watcher.s3.ap-northeast-1.amazonaws.com/2022/team-xxx.json

今天的爬蟲程式碼可以在 這裡 找到。


上一篇
D16 - 比喻 — 片場
下一篇
D18 - 不同的 CPU 架構 與 Image manifest
系列文
其實沒有那麼難 — Docker30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言