はじめに
みなさん技術記事はどこで読み漁っていますか?日本語のサイトだと今ならQiitaかZennといったところでしょうか?では英語のサイトなら?私は多くを知りませんが、DEVをよく巡回しています。
今日も暇つぶしにDEVを適当に見物していたら、ふと「最もいいね数が多い記事が読んでみたいんじゃ」という気持ちになりました。しかし、いいね数でソートする機能は提供されていないようでした(もしあったらごめんなさい🙇)。ないなら自分で作ろうということでこの記事に至ります。
API
DEVではAPIが提供されています。ちなみに、DEVはOSSのForemによるサイトなので、「APIドキュメントがDEV
じゃなくてforem
のものなんだが?」と思ってもそれはDEVのドキュメントとして読んで問題ないです。現在APIにはVersion-0とVersion-1が存在するようですが、今回はVersion-1を使用します。ただし、Version-1はAPIキーが必要ですので、まずはその準備から行います。
APIキーの発行はログインした状態で(https://dev.to/settings/extensions)にアクセスしてください。現在だと一番下にAPIキー発行のフォームがあります。
1ユーザー1APIキーではなく、いくつか発行できるようですのでDescription
に任意の値を入力してGenerate API Key
ボタンをクリックすればActive API Keys
に発行されたAPIキーが表示されます。漏洩には各自注意してください。下準備はこれだけです。
今回はいいね数で記事をソートして取得したいわけですが、記事一覧を取得するAPIがあります。こちらにソート機能あればやりたいことはすぐに終わってしまうわけですが、ないので記事をすべて取得してローカルで並び替える戦法でいきます。
そのために記事のレスポンスがどんな感じか見ていきましょう。以下はドキュメントのレスポンス例から拝借。
[
{
"type_of": "article",
"id": 4453,
"title": "East of Eden168",
"description": "Put a bird on it aesthetic narwhal xoxo pug. Disrupt slow-carb williamsburg crucifix...",
"readable_publish_date": "Aug 23",
"slug": "east-of-eden168-21ml",
"path": "/username372/east-of-eden168-21ml",
"url": "http://localhost:3000/username372/east-of-eden168-21ml",
"comments_count": 0,
"public_reactions_count": 0,
"collection_id": null,
"published_timestamp": "2022-08-23T12:08:21Z",
"positive_reactions_count": 0,
"cover_image": "http://localhost:3000/assets/24-377bc0861a9a539e8d1875ea9d4eea9e0226d93e1b6e9317e0c73c754699cc14.png",
"social_image": "http://localhost:3000/assets/24-377bc0861a9a539e8d1875ea9d4eea9e0226d93e1b6e9317e0c73c754699cc14.png",
"canonical_url": "http://localhost:3000/username372/east-of-eden168-21ml",
"created_at": "2022-08-23T12:08:21Z",
"edited_at": null,
"crossposted_at": null,
"published_at": "2022-08-23T12:08:21Z",
"last_comment_at": "2022-08-23T12:08:21Z",
"reading_time_minutes": 1,
"tag_list": [
"discuss"
],
"tags": "discuss",
"user": {
"name": "Angelena \"Charis\" \\:/ Lang",
"username": "username372",
"twitter_username": "twitter372",
"github_username": "github372",
"user_id": 10747,
"website_url": null,
"profile_image": "/uploads/user/profile_image/10747/79dbb51d-a63a-4475-af29-a84fe417b9d8.jpeg",
"profile_image_90": "/uploads/user/profile_image/10747/79dbb51d-a63a-4475-af29-a84fe417b9d8.jpeg"
},
"organization": {
"name": "Vandervort-Sanford",
"username": "org56",
"slug": "org56",
"profile_image": "/uploads/organization/profile_image/1275/45556538-13d9-44af-af7e-c9fcdbe2617c.png",
"profile_image_90": "/uploads/organization/profile_image/1275/45556538-13d9-44af-af7e-c9fcdbe2617c.png"
},
"flare_tag": {
"name": "discuss",
"bg_color_hex": "#000000",
"text_color_hex": "#ffffff"
}
}
]
ざっと記事に関するメタ情報が取得できている感じです。今回やりたいことはいいね数が欲しいわけですが、positive_reactions_count
キーが存在しますね。対象の全記事を取得してこちらの値で並び替えれば、やりたいことが実現できそうですね。
スクリプト
ということでスクリプトどーん。特に技術的に面白いところはないので、興味のある方だけなめてください。以下の流れで単純な処理を行っているだけです。
- 並び変えたい記事を
tag
指定でフェッチしていったんローカル保存
- ローカルから再度読み直して記事のリストを生成
- いいね数でソート
- 表に整形して出力
対象の全記事数がわからなくてページ数が特定できなかったので、空配列が帰ってきたら全部取得できたということにしているのは言い訳ポイントです。
main.py
import json
import time
from datetime import datetime
from pathlib import Path
import requests
ROOT_DIR = Path(__file__).parent
TEMP_DIR = ROOT_DIR / ".temp"
API_KEY = "secret"
HEADERS = {
"accept":"application/vnd.forem.api-v1+json",
"api-key":API_KEY
}
def sanitize_filename(filename):
return "".join([c for c in filename if c.isalpha() or c.isdigit() or c==' ']).rstrip()
def fetch_articles(directory, tag):
for page in range(1,100):
url = f"https://dev.to/api/articles?page={page}&per_page=1000&tag={tag}"
req = requests.get(url, headers=HEADERS)
print(req.status_code)
if req.json() == []:
break
filename = sanitize_filename(url) + ".json"
filepath = directory / filename
filepath.write_bytes(req.content)
time.sleep(5)
def load_articles(directory):
articles = []
articles_filepaths = directory.glob("*.json")
for article_filepath in articles_filepaths:
with open(article_filepath.as_posix()) as f:
articles.extend(json.load(f))
return articles
def create_table_row(rank_number, article):
ranking = f"{rank_number}位"
title = f"[{article['title']}]({article['url']})"
author = f"[{article['user']['name']}](https://dev.to/{article['user']['username']})"
published_at = f"{article['published_at']}"[:10].replace("-", "/")
reading_time_minutes = f"{article['reading_time_minutes']}分"
positive_reactions_count = f"{article['positive_reactions_count']}"
return f"| {ranking} | {title} | {author} | {published_at} | {reading_time_minutes} | {positive_reactions_count} |"
if __name__ == "__main__":
TEMP_DIR.mkdir(exist_ok=True)
work_dir = TEMP_DIR / f"{int(datetime.now().timestamp())}"
work_dir.mkdir()
fetch_articles(work_dir, "react")
articles = load_articles(work_dir)
sorted_articles = sorted(articles, key=lambda a : a["public_reactions_count"], reverse=True)
print("| 順位 | タイトル | 著者 | 公開日(UTC) | 読む時間 | いいね |")
print("| - | - | - | - | - | - |")
for i in range(0,100):
print(create_table_row(i+1, sorted_articles[i]))
reactタグのついた記事のいいね数ランキング
スクリプトで出力した内容は以下になります。以下はあくまで、実行時(2022年11月20日16:12:08 )の最新情報でしかないので、この記事が古くなればなるほど信用できなくなるのでご注意を。
順位 |
タイトル |
著者 |
公開日(UTC) |
読む時間 |
いいね |
1位 |
9 Projects you can do to become a Frontend Master |
Simon Holdorf |
2019/10/06 |
7分 |
12696 |
2位 |
Clean Architecture on Frontend |
Alex Bespoyasov |
2021/09/01 |
35分 |
5170 |
3位 |
The Complete Guide to Full Stack Ethereum and EVM Development |
Nader Dabit |
2021/04/09 |
18分 |
3968 |
4位 |
The Ultimate Guide to Web Performance 🚀 |
ender minyard |
2020/09/22 |
5分 |
3671 |
5位 |
35+ Free React templates and themes |
Davide Pacilio |
2020/06/02 |
15分 |
3616 |
6位 |
22 Miraculous Tools for React Developers in 2019 |
jsmanifest |
2019/08/06 |
13分 |
3428 |
7位 |
The React Cheatsheet for 2020 📄 (+ Real-World Examples) |
Reed Barger |
2020/01/19 |
17分 |
3378 |
8位 |
300+ React Interview Questions |
Michael Sakhniuk |
2021/01/05 |
128分 |
2968 |
9位 |
5 React Projects You Need In Your Portfolio 📂 |
Reed Barger |
2020/01/26 |
7分 |
2895 |
10位 |
A Complete Beginner's Guide to React |
Ali Spittel |
2018/08/28 |
15分 |
2829 |
11位 |
7 GitHub projects essential for every Javascript developer 👨🏽💻 🚀 |
Ankit Anand ✨ |
2021/06/28 |
3分 |
2632 |
12位 |
ReactJS Roadmap 🗺 For Developers 💻 |
ThemeSelection |
2020/10/06 |
9分 |
2508 |
13位 |
8 Projects with modern designs to become a Full-stack Master 2020 |
Thu Nghiem |
2020/09/02 |
4分 |
2354 |
14位 |
Practical Ways to Write Better JavaScript |
Ryland G |
2019/07/25 |
13分 |
2055 |
15位 |
React Interview Questions 🔥 |
Pramit Marattha |
2021/11/16 |
15分 |
2008 |
16位 |
Design Patterns in JavaScript |
Zeeshan Haider Shaheen |
2021/08/27 |
16分 |
1961 |
17位 |
The Complete Guide to Full Stack Solana Development with React, Anchor, Rust, and Phantom |
Nader Dabit |
2021/09/15 |
18分 |
1948 |
18位 |
React Cheat sheet (Updated June 2021) |
Eric The Coder |
2021/06/11 |
7分 |
1934 |
19位 |
Productive Tools🚀 For Web Development😎 |
Akshay Chougule |
2020/02/22 |
2分 |
1925 |
20位 |
Become a Full Stack Developer by building these amazing applications |
Yogesh Chavan |
2020/09/02 |
4分 |
1848 |
21位 |
8 Projects to Build to Master Your Front-End Skills 🥇🏆 |
Madza |
2021/08/05 |
5分 |
1813 |
22位 |
5 full-stack projects to add to your portfolio before 2020 ends 🤯 |
Chris Bongers |
2020/08/28 |
3分 |
1705 |
23位 |
Building a chat app with Socket.io and React 🚀 |
Nevo David |
2022/08/15 |
16分 |
1695 |
24位 |
Video Chatting and Screen Sharing with React, Node, WebRTC(peerjs) |
Arjhun777 |
2021/01/02 |
7分 |
1667 |
25位 |
⚛️ 🚀 React Component Patterns |
Alexi Taylor 🐶 |
2020/08/26 |
17分 |
1653 |
26位 |
21 React Example Projects to Learn From (Open-source, Beginner-Intermediate Level) |
Syakir Rahman |
2020/09/28 |
9分 |
1636 |
27位 |
Cheat Sheets that always save my time during web development 🚀 |
Mahesh Patidar |
2021/10/22 |
2分 |
1595 |
28位 |
How to learn React - The Effective way |
Shaan Alam |
2021/09/07 |
4分 |
1563 |
29位 |
No More ../../../ Import in React |
Nilanth |
2021/08/15 |
3分 |
1543 |
30位 |
16 Libraries You Should Know as a React Developer 💯🔥 |
Madza |
2022/10/04 |
3分 |
1526 |
31位 |
15 Free React Templates for Your Next Project |
ExWhyZee |
2021/04/15 |
6分 |
1521 |
32位 |
The vanilla Javascript basics to know before learning React JS |
Jane Tracy 👩🏽💻 |
2020/09/20 |
9分 |
1507 |
33位 |
My favorite resources being a freelancer as a side hustle 💎 |
leonardo jaques 👨🏻💻 |
2020/08/05 |
4分 |
1502 |
34位 |
Advanced JavaScript Design Patterns |
DhiWise |
2021/11/24 |
11分 |
1501 |
35位 |
How I structure my React projects |
Lars Wächter |
2021/08/31 |
5分 |
1490 |
36位 |
50 Cool Web And Mobile Project Ideas for 2021 |
Andrew Baisden |
2021/03/26 |
15分 |
1473 |
37位 |
Why I Stopped Using Redux |
Gabriel Abud |
2020/07/06 |
6分 |
1471 |
38位 |
ReactJs Roadmap🗺 for beginners - 2021 |
Suhail Shaikh |
2021/08/19 |
6分 |
1431 |
39位 |
26 Miraculous VS Code Tools for JavaScript Developers in 2019 |
jsmanifest |
2019/07/07 |
11分 |
1407 |
40位 |
20 GitHub Repositories to Become a React Master |
Martin Adams |
2022/08/04 |
5分 |
1397 |
41位 |
Top 20 JavaScript tips and tricks to increase your Speed and Efficiency |
Kapil Raghuwanshi🖥 |
2021/06/08 |
6分 |
1367 |
42位 |
Moving away from ReactJs and VueJs on front-end using Clean Architecture |
Jorge Sánchez Fernández |
2021/07/12 |
15分 |
1338 |
43位 |
8 Projects with Designs you can do to Become FRONT-END developer |
Thu Nghiem |
2020/07/02 |
2分 |
1337 |
44位 |
8 Awesome React Hooks |
Simon Holdorf |
2020/12/23 |
3分 |
1336 |
45位 |
Why You Shouldn't Use A Web Framework |
David Wickes |
2018/07/26 |
4分 |
1329 |
46位 |
Modern Full-Stack Developer Tech Stack 2021 |
Andrew Baisden |
2021/07/05 |
3分 |
1311 |
47位 |
How to deploy React App to GitHub Pages |
Ibrahim Ragab |
2019/06/23 |
2分 |
1310 |
48位 |
How to Build a Full Stack NFT Marketplace - V2 (2022) |
Nader Dabit |
2021/07/06 |
22分 |
1309 |
49位 |
JavaScript Basics Before You Learn React |
Nathan Sebhastian |
2019/01/14 |
9分 |
1266 |
50位 |
Making Sense of React Hooks |
Dan Abramov |
2018/11/02 |
11分 |
1217 |
51位 |
How to Reduce React App Loading Time By 70% |
Nilanth |
2021/09/14 |
5分 |
1194 |
52位 |
Top 42 React resources every developer should bookmark [Latest] |
Sunil Joshi |
2020/10/22 |
6分 |
1167 |
53位 |
useAxios : A simple custom hook for calling APIs using axios |
Yogini Bende |
2021/05/18 |
4分 |
1166 |
54位 |
Don't waste your time on a portfolio website |
Johannes Kettmann |
2020/10/20 |
8分 |
1158 |
55位 |
How to Build Scalable Architecture for your Next.js Project |
Alex Eagleson |
2022/04/06 |
32分 |
1152 |
56位 |
How to Create and Publish a React Component Library |
Alex Eagleson |
2021/11/17 |
24分 |
1140 |
57位 |
No, disabling a button is not app logic. |
David K. 🎹 |
2019/11/13 |
11分 |
1139 |
58位 |
17 Javascript optimization tips to know in 2021 🚀 |
Blessing Hirwa |
2021/01/25 |
5分 |
1135 |
59位 |
Bad Habits of Mid-Level React Developers |
Sam Magura |
2022/04/09 |
8分 |
1110 |
60位 |
Roadmap for React JS 2022 |
Digvijay Jadhav |
2021/12/07 |
4分 |
1086 |
61位 |
React Libraries To Use In 2021: 17 Top Picks |
Yash Tiwari |
2021/06/13 |
8分 |
1083 |
62位 |
Build a Pixel Perfect Skeleton Loader Using CSS 🚀 |
Ram Maheshwari ⚡ |
2021/09/15 |
5分 |
1073 |
63位 |
37 App Ideas for Bootcamp Students & Code Newbies |
Sylwia Vargas |
2019/12/01 |
4分 |
1066 |
64位 |
The Complete Modern React Developer 2022 |
Andrew Baisden |
2022/05/10 |
29分 |
1066 |
65位 |
Free hosting providers for front-end & back-end applications |
Vuelancer |
2020/09/10 |
2分 |
1058 |
66位 |
Just Redux: The Complete Guide |
Sanjeev Sharma |
2021/09/23 |
10分 |
1030 |
67位 |
Use Javascript console like pro |
Suprabha |
2021/05/16 |
3分 |
1021 |
68位 |
React Architecture for Enterprise Application |
Nilanth |
2021/11/06 |
4分 |
999 |
69位 |
Some projects to build your resume! |
Unnati Bamania |
2021/01/18 |
4分 |
999 |
70位 |
React Clean Code - Simple ways to write better and cleaner code |
Tyler Hawkins |
2021/02/22 |
2分 |
993 |
71位 |
What Front-End Developer Skills Should You Focus on Leading Into 2020? |
Marc Grabanski 🏙💻 |
2019/08/19 |
5分 |
992 |
72位 |
Understanding Rendering in React ♻ ⚛️ |
Mateo Garcia |
2021/01/31 |
6分 |
991 |
73位 |
Learn Deno: Chat app |
Aral Roca |
2020/05/10 |
10分 |
986 |
74位 |
Building a Notion-like system with Socket.io And React 😍 |
Nevo David |
2022/10/24 |
19分 |
982 |
75位 |
In defense of the modern web |
Rich Harris |
2020/05/15 |
6分 |
974 |
76位 |
10 Must-Know Patterns for Writing Clean Code with React and TypeScript✨🛀 |
Alex Omeyer |
2022/02/04 |
6分 |
968 |
77位 |
7 Tips for Clean React TypeScript Code you Must Know 🧹✨ |
Tapajyoti Bose |
2022/07/17 |
5分 |
967 |
78位 |
Free React resources you should have in your pocket. |
Jane Tracy 👩🏽💻 |
2020/09/27 |
6分 |
960 |
79位 |
Top 10 React Hook libraries |
Juraj Pavlović |
2020/10/19 |
6分 |
959 |
80位 |
39+ Advanced React Interview Questions (SOLVED) You Must Clarify (2020 Update) |
Alex 👨🏼💻FullStack.Cafe |
2019/11/04 |
18分 |
957 |
81位 |
How to make realtime APIs with NodeJS and ReactJS using Socket.io |
Omar Diaaeldine Elwakeel |
2021/08/25 |
5分 |
943 |
82位 |
I was creating Forms the wrong way all along in React.js 🤔 |
Kuvam Bhardwaj |
2022/08/01 |
4分 |
933 |
83位 |
Building a Kanban board with Node.js, React and Websockets 📝 ✨ |
Nevo David |
2022/09/28 |
18分 |
932 |
84位 |
Screaming Architecture - Evolution of a React folder structure |
Johannes Kettmann |
2022/02/25 |
16分 |
919 |
85位 |
Python Chat Tutorial with Django and React |
Nick Parsons |
2019/05/08 |
8分 |
917 |
86位 |
Redux Crash Course with Hooks 🎣 |
Chris Achard |
2019/10/02 |
3分 |
912 |
87位 |
The Complete Guide to Next.js Authentication |
Nader Dabit |
2020/09/21 |
8分 |
902 |
88位 |
7 code smells in your React components |
Anton Gunnarsson |
2020/11/09 |
9分 |
902 |
89位 |
11 Advanced React Interview Questions you should absolutely know (with detailed answers) |
Tapajyoti Bose |
2022/07/10 |
5分 |
880 |
90位 |
5 Good practices to scale your React projects easily |
Jeffrey Yu |
2022/08/07 |
3分 |
875 |
91位 |
Front-End Resources |
bleedeleventh |
2021/10/10 |
20分 |
873 |
92位 |
Want To Learn React in 2020? Here's The Blueprint to Follow. |
Reed Barger |
2020/01/06 |
7分 |
872 |
93位 |
10 Awesome Free Courses for Devs by Devs |
Simon Holdorf |
2021/01/04 |
8分 |
869 |
94位 |
How we reduced our initial JS/CSS size by 67% |
Guilherme Oenning |
2018/11/26 |
8分 |
867 |
95位 |
5 Tips to Take your Website Lighthouse Score from Meh to WOW! |
Tapajyoti Bose |
2021/11/07 |
4分 |
865 |
96位 |
34 UI Libraries For React, Vue And Angular |
Niemvuilaptrinh |
2021/02/03 |
7分 |
861 |
97位 |
Building a chat - Browser Notifications with React, Websockets and Web-Push 🤯 |
Nevo David |
2022/08/22 |
8分 |
859 |
98位 |
Building a sexy, mobile-ready navbar in any web framework |
Ben Holmes |
2020/10/06 |
9分 |
845 |
99位 |
The Full-Stack Developer Vocabulary(The Full List!) |
Code_Jedi |
2022/01/01 |
11分 |
841 |
100位 |
The React Cheatsheet for 2021 📄 (+ Real-World Examples) |
Reed Barger |
2021/01/09 |
23分 |
838 |
おわりに
今回はいろいろハードコードで済ませているところが多いので、皆さんもご自身のユースケースに合わせてスクリプトをいじるか汎用化して使ってもらったらいいかと思います。
Discussion