続・退職エントリを毎日自動で集めるBlogを作った ~過去編~


概要

この記事の続編です。

予想以上の反響を頂いたので、みんな退職エントリ読みたいんだなぁと思いました。


今回は

日付指定で退職エントリを拾ってきて、はてなBlogに投稿します。

ループさせれば過去分を一気に取得できますね。やりましたね。


退職エントリをあつめる

前回のコードを変更します。変更したとこメインで抜粋します。

微妙に変数名が違ったりするのはリファクタリングしてるからです。

// moment使うと日付処理が楽です

const moment = require('moment');

// "tbs=cdr:1,cd_min:%DATE%,cd_max:%DATE%"を指定すると日付指定の検索ができる(%DATE%は後で置換する)
const BASE_URL_GOOGLE =
'https://www.google.com/search?q=%22%E9%80%80%E8%81%B7%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F%22&tbs=cdr:1,cd_min:%DATE%,cd_max:%DATE%&start=';

const getEntries = async moment => {
const entries = [];
for (let i = 0; ; i += 10) {
const date = moment.format('M/D/YYYY');
// minとmaxに同じ日付を入れると、その日のみの検索になる。
const res = await client.fetch(
`${BASE_URL_GOOGLE.replace(/%DATE%/g, date)}${i}`
);
const contents = res.$('div.r > a > h3');
if (contents.length === 0) {
break;
}
contents.each((index, elm) => {
const url = elm.parent.attribs.href;
const title = elm.childNodes[0].data;
if (!title) {
return;
}
if (!includesIgnoreSites(url) && includesRetirementWords(title)) {
entries.push({ url: url, title: title });
}
});
}
return entries;
};


はてなブログAPIで投稿する

const postBlog = async (entries, moment) => {

const title = `${moment.format('YYYY-M-D')}の退職エントリ`;
let content = '';
for (const entry of entries) {
if (content !== '') {
content += '\r\n';
}
content += `[${entry.url}:embed:cite]`;
}
if (content === '') {
return;
}
// updatedタグで、投稿日時を決めれる。
const data = `<?xml version="1.0" encoding="utf-8"?>
<entry xmlns="http://www.w3.org/2005/Atom"
xmlns:app="http://www.w3.org/2007/app">
<title>
${title}</title>
<content type="text/x-markdown">
${content}
</content>
<updated>
${moment.format('YYYY-MM-DD')}T00:00:00</updated>
</entry>`
;

await axios.post(
'https://blog.hatena.ne.jp/{はてなID}/{ブログID}/atom/entry',
data,
{ auth: { username: /* はてなID */, password: /* APIキー */ } }
);
};


自動投稿する

あとは、日付したmomentオブジェクトでそれぞれのメソッドを呼び出せばOK。

mom.add(1, 'days')とかで日付計算しつつ、ループさせれば過去分一気に投稿!

良いですね。

…とは、行きませんでした。

Google検索のリクエスト制限に引っかかって、429が返ってきちゃうので、

1週間ごととかにリクエストを分けて送るのが良さそうでした。

現場からは以上です。