Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
9
Help us understand the problem. What is going on with this article?
@HelloRusk

Netlify Functions を使って Qiita のトレンド API を非公式で作ってみた

Zenn 版はこちら


Qiita の API にはトレンド記事一覧を取得する API が無いので、作ったみたという話です。
早速試してみたい方は

https://qiita-api.netlify.app/.netlify/functions/trend

または

https://qiita-api.netlify.app/trend.json

を確認してみてください。
(万一上手く取得できていない場合はコメント欄かリポジトリの Issue にてお知らせください。)

背景

QiitaAPIにトレンドが見当たらないので泣いてたら という記事に経緯がありますが、かつてはトレンド記事一覧は https://qiita.com/trend.json を GET することで得られたものの、2019年12月現在は公式には API が提供されていません。
ただ、トップ画面の div タグに埋め込まれる形で JSON (の文字列)があり、これをスクレイピングすることで記事一覧を得ることができます。
 
わざわざスクレイピングするのは面倒だという気持ちになったので、直接 JSON を返せるような URL を自前で立てることにしました。

Netlify Functions

Netlify 上で AWS Lambda を使えるというものです。
無料だと Requests が 125,000/月, Runtime が 100 hours/月 (2019年12月現在)まで使えるので、趣味プロダクトなら全然余裕の範囲ですね。

どう使っているか

以下のような関数を書いています。Qiita の URL を axios で GET して、cheerio でパースしているだけなので、非常に単純ですね。

src/lambda/trend.ts
import axios from 'axios'
import cheerio from 'cheerio'

const fetchTrend = (html: string) => {
  const $ = cheerio.load(html)
  const raw = $('script[data-component-name=HomeArticleTrendFeed]').html() ?? ''
  if (raw === undefined) return {}
  const rawData = JSON.parse(raw).trend.edges

  return rawData.map(obj => {
    // 不要なプロパティを削除
    delete obj.followingLikers
    delete obj.isLikedByViewer

    delete obj.node.isLikedByViewer
    delete obj.node.isStockableByViewer
    delete obj.node.isStockedByViewer
    delete obj.node.followingLikers
    delete obj.node.recentlyFollowingLikers

    return obj
  })
}

export const handler = async () => {
  const url = 'https://qiita.com/'

  return await axios
    .get(url)
    .then(({ data }) => {
      return {
        statusCode: 200,
        headers: {
          'Access-Control-Allow-Origin': '*',
          'Content-Type': 'application/json; charset=utf-8'
        },
        body: JSON.stringify(fetchTrend(data)),
      }
    })
    .catch(err => {
      return {
        statusCode: 500,
        body: err,
      }
    })
}

Lambda 本体の実装の他は、基本的には netlify.toml.babelrc をいじるだけです。詳しくは


をご確認ください。

参考になるリンク

9
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
9
Help us understand the problem. What is going on with this article?