掘金排行前5000大佬 | 掘金文章排行 看這裏

文章教你如何作掘金站內數據抓取,數據解析,最後造成排序後的排名。前端

0821更新: 掘金總點贊量前 5000 排行發佈 | 掘金總關注量前 5000 排行(20190821)vue

0827更新: 【第三方掘金功能】掘金我的數據統計,第三方實現的掘金用戶 dashboardnode

項目原由是我忽然想看看掘金站內有哪些優質做者,爲了避免錯過每個大佬,我選擇直接抓取站內全部的文章信息找到做者並進行排名。各位關注 + 文章閱讀 一條龍走起!webpack

項目地址 juejin-spider 歡迎 star issueios

掘金 spider 和數據分析,主要關注了下面幾個排行和統計,排行點擊直接查看git

先上掘金前50排名,關注一波???? 前5000排名看這裏程序員

🎉 等級,👦 關注數,🏠公司github

腳本

全站標籤抓取

獲取掘金站內全部標籤信息web

npm run tagList
複製代碼

會把標籤信息寫入到 src/assets/tagList/tagList.json,每一個標籤包含下面的信息,主要是 titleid面試

{
  "id": "5597a063e4b08a686ce57030",
  "title": "後端",
  "createdAt": "2015-07-04T00:59:16Z",
  "updatedAt": "2017-06-18T23:34:00Z",
  "color": "#C679FF",
  "icon": "https://lc-gold-cdn.xitu.io/d83da9d012ddb7ae85f4.png",
  "background": "",
  "showOnNav": true,
  "relationTagId": "",
  "alias": "backend houduan",
  "isCategory": true,
  "entryCount": 19840,
  "subscribersCount": 295562,
  "isSubscribe": false
},
複製代碼

全站文章抓取

將會採集全站全部標籤下面的全部文章,採集過程會由於網速和機器性能表現出差別,請各位耐心等待採集完成

這一步採集的數據很是重要,是後面全部分析的基礎

採集到的文件會存放在 src/assets/articleData 下面,包含有不少 json 文件,每一個文件包含這個標籤下的全部專欄文章元信息

npm run allTagData
複製代碼

數組中每一個對象

{
  "collectionCount": 5, // 點贊數
  "userRankIndex": 5.4006856695164,
  "buildTime": 1565582852.8327,
  "commentsCount": 2, // 評論數
  "gfw": false,
  "objectId": "5d40d29d518825221b4cbb40",
  "checkStatus": true,
  "isEvent": false,
  "entryView": "",
  "subscribersCount": 0, // 無用
  "ngxCachedTime": 1565627197,
  "verifyStatus": true,
  "tags": [
    {
      "ngxCachedTime": 1565627193,
      "ngxCached": true,
      "title": "React.js",
      "id": "555e99ffe4b00c57d99556aa"
    }
  ],
  "updatedAt": "2019-08-12T04:07:32.818Z",
  "rankIndex": 0.005346156248974,
  "hot": false,
  "autoPass": false,
  "originalUrl": "https://juejin.im/post/5d3ef3646fb9a06b1b1999fd", // 文章的 url
  "verifyCreatedAt": "2019-07-31T01:36:14.238Z",
  "createdAt": "2019-07-31T01:36:14.238Z",
  "user": {
    "community": {
      "weibo": { "uid": "5345591282", "nickname": "歲月痕跡A88" },
      "wechat": {
        "avatarLarge": "http://thirdwx.qlogo.cn/mmopen/vi_32/cabLXAUXiavVhiaDh2050AOOEToUvnZTWsSNqqKZC4hzPzHABC7fxwv6VxwebIxfKdaRkYDZoic8UXfonLDyiafuiaw/132"
      },
      "github": {
        "username": "lxfriday",
        "avatarLarge": "https://avatars0.githubusercontent.com/u/20264467?v=4",
        "uid": "20264467"
      }
    },
    "collectedEntriesCount": 154, // 點贊數
    "company": "xxx", // 公司
    "followersCount": 35, // 被關注數
    "followeesCount": 70, // 關注數
    "role": "guest", // 用戶角色
    "postedPostsCount": 19, // 發佈的專欄數
    "level": 2, // 用戶等級
    "isAuthor": false,
    "postedEntriesCount": 2, // 分享數?
    "totalCommentsCount": 16, // 總評論數
    "ngxCachedTime": 1565627197,
    "viewedEntriesCount": 1347, // 查看的文章數
    "jobTitle": "前端", // 工做:前端
    "subscribedTagsCount": 166, // 關注的標籤數
    "totalCollectionsCount": 120, // 總收藏數
    "username": "雲影sky", // 用戶名
    "avatarLarge": "https://user-gold-cdn.xitu.io/2019/7/14/16bf1155693d96c2?w=570&h=488&f=png&s=312610",
    "objectId": "57a0c28979bc440054958498" // 用戶 id
  },
  "author": "",
  "screenshot": "https://user-gold-cdn.xitu.io/2019/7/29/16c3e3d979a96831?w=1097&h=573&f=png&s=58239",
  "original": true,
  "hotIndex": 21.2095,
  "content": "給 PureComponent 從新指向構造函數以後,_assign 複製對象屬性時, Component 構造函數不會覆蓋 PureComponent 構造函數,看下面的例子就明白了。 把 PureComponent 變成 Component,userInfo 可正常變化。",
  "title": "React 源碼系列-Component、PureComponent、function Component 分析",
  "lastCommentTime": "2019-08-03T16:53:20.577Z",
  "type": "post",
  "english": false,
  "category": {
    "ngxCached": true,
    "title": "frontend",
    "id": "5562b415e4b00c57d9b94ac8",
    "name": "前端",
    "ngxCachedTime": 1565627098
  },
  "viewsCount": 267, // 瀏覽量
  "summaryInfo": "通過 處理以後,三個組件的區別就是 type 不同了 和 看不懂能夠看下這篇文章 https://www.zhihu.com/question/34183746 js 中 和 的區別和關係 函數的 屬性對象上的 是不可枚舉的,因此下面兩句 給 PureComponent 從新指向構造函數以後, ...",
  "isCollected": false
}
複製代碼

關注量排行

獲取站內瀏覽量

npm run follower
複製代碼

腳本執行完成會產生兩個文件

  • src/assets/calcUserRank/用戶followerRank.json 是排行後的元信息
  • src/assets/calcUserRank/用戶followerRank.md 按排名編排的 md 文檔

點贊排行

獲取站內點贊排行

npm run dianzan
複製代碼

腳本執行完成會產生兩個文件

  • src/assets/calcDianzanRank/點贊rank.json 是排行後的元信息
  • src/assets/calcDianzanRank/點贊rank.md 按排名編排的 md 文檔

例子

全站文章瀏覽量排行

獲取站內瀏覽量

npm run view
複製代碼

腳本執行完成會產生兩個文件

  • src/assets/calcViewRank/瀏覽量rank.json.json 是排行後的元信息
  • src/assets/calcViewRank/瀏覽量rank.json.md 按排名編排的 md 文檔

全站文章評論量排行

獲取站內瀏覽量

npm run comment
複製代碼

腳本執行完成會產生兩個文件

  • src/assets/calcCommentRank/calcCommentRank.json 是排行後的元信息
  • src/assets/calcCommentRank/calcCommentRank.md 按排名編排的 md 文檔

技術解析

  • async 併發控制
  • chalk 多彩命令行
  • request 發送 http 請求
  • request-promise 把 request promise 化,方便使用 async

項目輔助工具 dev assistant

  • commitlint 規範 commit message
  • eslint 你們都懂
  • prettier 自動格式化代碼
  • husky 提供 git 鉤子
  • lint-staged 只對當前變更的文件執行格式化和 eslint 校驗
  • jest 測試排序算法正確性

前 1000、前 5000 在20w條數據中是如何計算的

構建小頂堆,不斷往堆中添加數據,比堆頂小的直接拋棄,比堆頂大的,替換成堆頂並對二叉樹進行調整,維持小頂堆。遍歷全部數據以後 小頂堆就是咱們要的全部最大值排行,再對這個數組排序依次就能夠獲取排名了!!!

// 最小值上浮
function heapify(arr, len, i, compareVal) {
  let min = i
  const l = 2 * i + 1
  const r = 2 * i + 2

  if (l < len && compareVal(arr[l]) < compareVal(arr[min])) min = l
  if (r < len && compareVal(arr[r]) < compareVal(arr[min])) min = r

  if (min !== i) {
    swap(arr, i, min)

    heapify(arr, len, min, compareVal)
  }
}

/** * 對 target 建堆 * @param {array} target 堆數組 * @param {*} compareVal 從 dataUnit 對象獲取比對值 */
function createHeap(target, compareVal = v => v) {
  for (let i = Math.floor((target.length - 1) / 2); i >= 0; i--) {
    heapify(target, target.length, i, compareVal)
  }
}

function findMaxPrev(dataUnit, target, compareVal = v => v) {
  if (compareVal(dataUnit) > compareVal(target[0])) {
    target[0] = dataUnit
    heapify(target, target.length, 0, compareVal)
  }
}
複製代碼

排行

瀏覽量排行

👀 瀏覽量,📌 標籤

點贊量排行

👍 點贊數,📌 標籤

'掘金' === '前端社區' ????

評論量排行

🐶 評論數,📌 標籤

分析的內容就是這些了,我還統計了掘金站內的總的文章數和在標籤下發布文章的用戶總數

  • 掘金站內去重後總的文章數:10w 左右,可能統計有很大偏差,去重前是 20+w
  • 標籤下發布文章的用戶總數:1.5w 左右

看看 npm scripts 開始玩耍吧

npm run all 一行命名抓取數據分析全流程走完,整個流程處理的數據量比較大,須要半個小時左右

"scripts": {
    "all": "npm run tagList && npm run allTagData && npm run dianzan && npm run view && npm run comment && npm run follower",
    "start": "npm run tagList",
    "tagList": "TASK=tagList node App.js",
    "allTagData": "TASK=allTagData node App.js",
    "composeArticleData": "TASK=composeArticleData node App.js",
    "userData": "TASK=userData node App.js",
    "dianzan": "TASK=dianzan node App.js",
    "view": "TASK=view node App.js",
    "comment": "TASK=comment node App.js",
    "follower": "TASK=follower node App.js",
    "lint": "eslint .",
    "test": "jest"
},
複製代碼

最後歡迎你們關注個人 github 和 微信公衆號

相關文章
相關標籤/搜索