我從CSDN排行榜上發現驚人的秘密,快進來看看吧~
本篇文章盡量不使用的晦澀復雜的技術手段,僅僅利用簡單的前端知識和相關api,配合瀏覽器獲得我們想要的資料,進行分析
希望本篇文章可以讓技術大佬會心一笑,回想自己當年是否也會有類似的的“奇葩”研究呢吧
也許這篇文章會勾起你當初從事技術作業時最純粹的初衷
一、前言
CSDN是我大學時接觸的第一個技術社區,最近它增加了排行榜板塊,里面細分了十幾個分類,從互動、點贊、評論、收藏、時間緯度計算得到每篇文章的熱度,將他們投放到對應的分類,最侄訓聚成分類榜單和綜合榜單,
社區在大力的鼓勵大家進行技術分享和沉淀,以推動整個技術圈的發展,本篇文章也是因為我在瀏覽排行榜時的一個念頭而誕生的,那就是我想從用戶的視角:
- 統計各個榜單的文章標題+作者+所在榜單
- 將匯總的榜單資料整合,并做出一份新的“綜合領域榜單”
- 統計綜合領域榜單,看看有沒有財富密碼,哈哈
用互聯網黑話應該是這樣的:
- 在細分領域找到抓手
- 形成方法論,對外輸出
- 分析自己的痛點,做精細化運營

二、開始行動
下面的代碼都可以直接運行在瀏覽器控制臺中,且我們盡量從用戶的操作出發,避免給整個實作增加難度,
2.1 一條榜單內容我能得到什么
思路:
- 選中單條內容
- 獲取內容內的標題、作者、熱度
代碼:
// 選中單條內容
const hotRankItem = document.querySelector('.hostitem');
// 獲取標題
hotRankItem.querySelector('a.title').innerText;
// 獲取作者
hotRankItem.querySelector('a.name').innerText;
// 獲取熱度
hotRankItem.querySelector('span.num').innerText;
結果:

2.2 獲取一個榜單完整的資料
思路:
- 獲取內容串列,并轉換成陣列
- 遍歷獲取所需內容,并回傳陣列
代碼:
function getData() {
const likeArray = (arr) => Array.prototype.slice.call(arr)
// 獲取串列陣列
const hotRankList = likeArray(document.querySelectorAll('.hostitem'));
// 處理榜單內所有資料
const newHotRankList = hotRankList.map((element, index) => {
const title = element.querySelector('a.title').innerText;
const name = element.querySelector('a.name').innerText;
const hot = element.querySelector('span.num').innerText;
return {title, name, hot}
})
return newHotRankList;
}
getData()
結果:

注意
經常瀏覽排行榜的小伙伴可能意識到了,出于性能和體驗的考慮,只有用戶劃到頁面底部,才會更新排行榜單后續的內容,每次新增25條,所以我們也像一個真正的用戶一樣,讓代碼幫我們做實作瀏覽閱讀行為好啦~
2.3 模擬用戶滑動獲取完整榜單
思路:
- 借助
window.scrollTo(x, y)可把內容滾動到指定的坐標, - 已知每次加載25條資料,單榜共50條資料,綜合榜共100條資料
- 利用回呼函式來確定處理資料的時機
代碼:
function getData() {
const likeArray = (arr) => Array.prototype.slice.call(arr)
// 獲取串列陣列
const hotRankList = likeArray(document.querySelectorAll('.hostitem'));
// 處理榜單內所有資料
const newHotRankList = hotRankList.map((element, index) => {
const title = element.querySelector('a.title').innerText;
const name = element.querySelector('a.name').innerText;
const hot = element.querySelector('span.num').innerText;
return {title, name, hot}
})
return newHotRankList;
}
function getComData(){
let mainHeight = 0; // 內容高度
let timer = setInterval(() => {
let height = document.querySelector('.main').offsetHeight
if (mainHeight === height) {
const res = getData();
console.log(res)
clearInterval(timer);
} else {
mainHeight = height
window.scrollTo({
top: 100000,
behavior: "smooth"
})
}
}, 1000)
}
getComData();
結果:

2.4 獲取所有領域內容榜的資料
之后的所有示例,默認先執行本小節的代碼
同樣,如果我是用戶且我想看過所有的榜單,我的操作應該是這樣的
- 瀏覽C/C++榜單,劃至底部(閱讀完畢)
- 點擊Java分類,繼續步驟1->步驟2
- 注意:此時用獲取完整串列的方法使用了Promise

思路:
- 回圈模擬用戶點擊
- 進入新的榜單,重復2.3小節的操作
- 將所有的榜單的結果匯總,并獲取榜單名稱用于區分
const likeArray = (arr) => Array.prototype.slice.call(arr)
function getData() {
// 獲取串列陣列
const hotRankList = likeArray(document.querySelectorAll('.hostitem'));
const curBlogRankName = document.querySelector('.blog-rank-right-top li.active').innerText;
console.log(`正在拉去${curBlogRankName}榜單資料`)
// 處理榜單內所有資料
const newHotRankList = hotRankList.map((element, index) => {
const title = element.querySelector('a.title').innerText;
const name = element.querySelector('a.name').innerText;
const hot = element.querySelector('span.num').innerText;
return {title, name, hot, curBlogRankName}
})
return newHotRankList
}
function getComData(){
let mainHeight = 0; // 內容高度
return new Promise((resolve, reject)=>{
let timer = setInterval(() => {
let height = document.querySelector('.main').offsetHeight
if (mainHeight === height) {
const res = getData();
resolve(res);
clearInterval(timer);
} else {
mainHeight = height;
window.scrollTo({
top: 100000,
behavior: "smooth"
})
}
}, 1000)
})
}
// 獲取串列榜單
async function loopNav(curList) {
const result = {}
let i = 0;
const navList = likeArray(document.querySelectorAll('.blog-rank-right-top ul li'));
for(let i = 0; i < navList.length; i++){
navList[i].click();
const res = await getComData();
result[navList[i].innerText] = res;
}
console.log('榜單結果匯總:', result)
window.rankResult = result; // 將結果掛到window物件上
}
loopNav();
結果:

2.5 獲取單個榜單資料集合
如果大家想要獲取某個榜單內容:
例如:在CSDN全站綜合熱榜頁面,打開控制臺,執行2.3小節的代碼
就可以的得到陣列型別的資料,
三、拿到資料開始整活
我們拿到的資料應該下面這樣的,按照第一章的思路,還要對其進行處理,
集合:{
榜單1:[
{文章1}, {文章1},
],
榜單1:[
{文章1}, {文章1},
]
}
3.1 熱度最高的前100名單
有人可能會問,會什么不直接看綜合熱榜,這是因為單榜和熱榜更新時間不同,其實任選其一往深研究即可,
思路:
- 所有榜單合并
- 按熱度排序
- 截取前100名
代碼:
window.rankResult100 = Object.keys(rankResult)
.reduce((prev, next) => prev.concat(rankResult[next]), [])
.sort((a, b) => b.hot - a.hot)
.slice(0, 100)
console.log('熱度前100名(每日更新):', window.rankResult100)
結果:

emmm 可以看到,此時排在第一的是運維榜單-<程式猿是小賀>大佬的文章,
3.2 統計前100名中出現的領域模塊
實作此需求的方式有很多,不要糾結方式~
代碼:
window.rankResult100 = Object.keys(rankResult)
.reduce((prev, next) => prev.concat(rankResult[next]), [])
.sort((a, b) => b.hot - a.hot)
.slice(0, 100)
console.log('熱度前100名(每日更新):', window.rankResult100)
// 統計榜單進去前100的數量
window.rankResultGroup = {};
// 獲取榜單名稱并生成Key
const navList = Array.prototype.slice.call(document.querySelectorAll('.blog-rank-right-top li'))
.map(item => item.innerText)
.forEach(item => window.rankResultGroup[item] = 0)
// 統計數量
window.rankResult100.forEach(item => window.rankResultGroup[item.curBlogRankName]++);
console.log('各榜單擁有前100數量:', window.rankResultGroup);
結果:

3.3 榜單“分析”結論——模塊排名占有率高 和 語言使用率存在一定關系
怎么看,都像一句廢話
使用的人多:
- 遇到的問題就多
- 解決問題的人就多
- 技術沉淀就多
雖然我不是專業做資料分析的,但在知乎隨便翻了一下編程語言熱度排行,在TIOBE 公布的 2020年9月的編程語言排行榜,可以看到前三名是 C、Java 和 Python,如圖:

對比我們最后得到的結果:

嗯~相差不大,

3.4 小結
截止到此時,我們完成了:
- 獲取榜單資料
- 整合榜單資料
- 統計若干排名的文章
- 統計單榜選手在綜合榜100名內的數量
- 簡單的分析(虛心接受指教)
而這也讓我對 click、dom操作、陣列操作等加深了印象,希望讀到這里的同學也能有所識訓,當然上面的代碼一定有可以改進的地方的地方,歡迎各位大佬留言互動哦~
之后還能怎么做?我期待大家也能參與進來,和我和或其他人進行自己領域內的互動,例如:
- 生成二維、三維的資料模型;
- 分析上榜作者的粉絲數量,進一步得到對自己有用的資訊;
- 獲取榜單文章的發布時間,統計大佬們的發布時間規律
- …
也許一條隱密的捷徑就在你感興趣、你正在探索的事情中,加油!

四、寫在最后
本篇文章是技術與生活結合一篇文章,我將它定義為something interesting,也會同步在《余光的前端進階筆記》中
讀到這里的同學不妨做件小事,給我的GitHub倉庫點個star吧!Thanks?(・ω・)ノ
關于我
- 花名:余光
- WX:j565017805
- 郵箱:webbj97@163.com
其他沉淀
- Github: Js 版 LeetCode 題解
- 前端進階筆記
- CSDN 博客匯總
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/286330.html
標籤:其他
