DevelopersIOの指定のURLの記事ページが存在しているかNodejs(Axios)で判定する

2022.11.07

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、CX事業本部 IoT事業部の若槻です。

DevelopersIOの記事執筆を効率化させることに日々余念が無い今日この頃なのですが、このたびその一環としてDevelopersIOの指定のページが既に存在しているかをスクリプトで判定させる必要が生じました。

そこで今回は、DevelopersIOの指定のページが存在しているかをNodejsで判定する方法を確認してみました。

やってみる

モジュールはAxiosを使用しました。

npm i axios

ページが存在することを確認する

指定のURLの記事ページが存在することを確認してみます。そこで下記のスクリプトを作成しました。

check_status.js

const axios = require('axios'); 

const TARGET_URL = process.argv[2];

const main = async (targetUrl) => {
  const response = await axios.get(targetUrl)
  console.log(response.status);
};

main(TARGET_URL);

記事ページが存在するURL`https://dev.classmethod.jp/articles/cm_hikkoshi/`を指定してスクリプトを実行すると、ステータスコード`200`が取得でき、**指定のURLのページが存在すること**が確認できました。

# ページが存在するURLを指定
$ node check_status.js https://dev.classmethod.jp/articles/cm_hikkoshi/
200

ページが存在しないことを確認する

指定のURLの記事ページが存在しないことを確認してみます。

記事ページが存在しないURL`https://dev.classmethod.jp/articles/sonna-page-ha-nai/`を指定してスクリプトを実行すると、実行がエラーとなりました。AxiosではレスポンスがBAD REQUESTの場合は実行が失敗するようです。

# ページが存在しないURL
$ node check_status.js https://dev.classmethod.jp/articles/sonna-page-ha-nai/

/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/devio/node_modules/axios/dist/node/axios.cjs:1268
    reject(new AxiosError(
           ^
AxiosError: Request failed with status code 404
    at settle (/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/devio/node_modules/axios/dist/node/axios.cjs:1268:12)
    at Unzip.handleStreamEnd (/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/devio/node_modules/axios/dist/node/axios.cjs:2446:11)
    at Unzip.emit (node:events:539:35)
    at endReadableNT (node:internal/streams/readable:1345:12)
    at processTicksAndRejections (node:internal/process/task_queues:83:21) {
  code: 'ERR_BAD_REQUEST',
  
  (中略)
  
  }
}

そこでTry/Catchをするように下記の通りスクリプトを修正します。

check_status.js

const axios = require('axios'); 

const TARGET_URL = process.argv[2];

const main = async (targetUrl) => {
  try {
    const response = await axios.get(targetUrl)
    console.log(response.status);
  } catch (error) { 
    console.log(error.response.status); 
  }
};

main(TARGET_URL);

改めて記事ページが存在しないURLを指定してスクリプトを実行すると、ステータスコード404が取得でき、指定のURLのページが存在しないことが確認できました。

$ node check_status.js https://dev.classmethod.jp/articles/sonna-page-ha-nai/
404

リダイレクトに対応させる

さて、DevelopersIOのサイトの仕様として、リクエストされた記事ページのURLが存在しない場合はslugを自動補完してリダイレクトを行うようになっています。

例えば、`https://dev.classmethod.jp/articles/classmethod/`は、`https://dev.classmethod.jp/articles/classmethod_i_have_returned/`にリダイレクトされる動作となります。

上記のリダイレクトされるURLを指定してスクリプトを実行すると、ステータスコード200が取得されてしまいました。期待値としてはリダイレクトされたことが分かる301が取得されて欲しかったのですが出来ていません。

# リダイレクトされるURL
$ node check_status.js https://dev.classmethod.jp/articles/classmethod       
200

そこで対処方法を調べたところ、AxiosではRequest ConfigmaxRedirects0とすることにより、リダイレクトを抑制できるとのこと。

// maxRedirects defines the maximum number of redirects to follow in node.js. // If set to 0, no redirects will be followed. maxRedirects: 21, // default

そこでスクリプトを下記の通り修正します。

check_status.js

const axiosBase = require('axios')
const axios = axiosBase.create({
  responseType: 'json',
  maxRedirects: 0
})

const TARGET_URL = process.argv[2];

const main = async (targetUrl) => {
  try {
    const response = await axios.get(targetUrl)
    console.log(response.status);
  } catch (error) { 
    console.log(error.response.status); 
  }
};

main(TARGET_URL);

改めてリダイレクトされるURLを指定してスクリプトを実行すると、ステータスコード301が取得でき、指定のURLのページが存在しないこと(リダイレクトされること)が確認できました。

$ node check_status.js https://dev.classmethod.jp/articles/classmethod
301

おわりに

DevelopersIOの指定のページが存在しているかをNodejsで判定する方法を確認してみました。

今回の検証により、3XX4XXの時は存在していないという判定を行うことができそうです。

参考

以上