🕶️
よく使うのに毎回書いてるnode.jsのスクレイピングをいい加減テンプレ化した
node.jsのスクレイピングをテンプレ化した
使っているもの
目的
node.jsでスクレイピングするのに一番直感的に書きやすいのでcheerioを選択。
今回は某エンジニア案件のサイトの投稿をぶん回して
マッチした案件をメールで受信するために使用。
プロジェクト作る
yarn init -y
依存関係
yarn add cheerio nodemailer request-promise
もしくはCloneする
git clone git@github.com:abalol/node-scraping-template.git
package.json
{
"name": "node-scraping-template",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"mail": "node index.js mail",
"text": "node index.js text",
"serve": "node index.js mail 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"cheerio": "^1.0.0-rc.3",
"nodemailer": "^6.4.16",
"request": "^2.88.2",
"request-promise": "^4.2.6",
"sendmail": "^1.6.1"
}
}
index.js
const cheerio = require('cheerio');
const fs = require("fs");
const nodemailer = require('nodemailer');
const rp = require('request-promise');
/**
* 出力先を設定します。true:ファイル false:メール
* @type {boolean}
*/
const isMakeFile = process.argv[2] === 'text';
/**
* 繰り返し処理のインターバルを時間単位で指定します
* 未設定時は1時間置き
* @type {Number}
*/
const interval = !process.argv[3] ? null : Number(process.argv[3]);
// 複数ページ取得
const promises = [...Array(3)].map((_, i) => {
return `ここにURL?page=${i + 1}`
}).map(async(url) => {
const $ = await rp.get(url, {
transform: (body) => {
return cheerio.load(body);
}
});
return $('.title').map((i, el) => {
return `ここで適宜中身をパース`;
}).get().join(' ');
});
const getNewPosts = async() => {
await Promise.all(promises).then((result) => {
if (isMakeFile) {
const fileName = `${getCurrentTime}_list.tsv`;
if (isMakeFile && fs.existsSync(fileName)) fs.unlinkSync(fileName);
fs.writeFile(fileName, result.flat().join('\n'), {
flag: 'wx'
}, (err) => {
if (err) throw err;
console.log(`${getCurrentTime()}出力`);
});
} else {
// TODO: GMailの送信はセキュリティ弱くなるので非推奨
const smtpConfig = {
host: 'smtp.gmail.com',
port: 465,
secure: true,
auth: {
user: 'あなたのGMailアカウント',
pass: 'GMailのパスワード'
}
};
const transporter = nodemailer.createTransport(smtpConfig);
transporter.sendMail({
from: '送信元アドレス',
to: '送信先アドレス',
subject: `タイトル ${getCurrentTime()}`,
text: result.flat().join('\n\n'),
}, (err, reply) => {
if (err) console.log(err && err.stack);
console.dir(reply);
});
}
});
}
// 一回実行 or 繰り返し実行
if (!interval) {
getNewPosts()
} else {
// 開始時即時実行
getNewPosts()
setInterval(getNewPosts, 1000 * 60 * 60 * interval);
}
const getCurrentTime = () => {
const n = new Date();
return `${n.getFullYear()}/${pz(n.getMonth() + 1)}/${pz(n.getDate())} ${pz(n.getHours())}/${pz(n.getMinutes())}`;
}
const pz = (num) => {
return result = num < 10 ? `${0}${num}` : num;
}
Setup
- メール送信時は
smtpConfig
とsendMail
を適宜修正する - package.jsonの引数で繰り返し時のインターバルの設定を行える
例
常駐して1時間置きにメール送信させる
yarn run serve
1回実行してローカルに.tsvを作成する
yarn run text
Spreadsheetに送信もそのうち。
Discussion