已參與了 SegmentFault 思否社群 10 週年「問答」打卡 ,歡迎正在閱讀的你也加入。
最近 「SegmentFault 思否社群 10 週年「問答」打卡」 十分火熱,但是有一個小問題,經常不知道是否完成今天的 KPI,以及小尾巴是否正常新增,那我們今天來做個小工具。
分析
- 先開啟個人的問答頁
- 查詢是否有單獨拉問答資料的介面。(感謝官方老闆在後期做過優化,直接有介面)
- 右鍵 copy as fetch 我們就可以快樂的使用了
改造&迴圈
改造成可以查出所有資料,並且過濾掉不感興趣的資訊(graphql 的就更好了,可惜不是)
getAnswers = function(username, page = 1, startTime = new Date('2022-06-01 00:00:00.000').getTime() / 1000){
return fetch(`https://segmentfault.com/gateway/homepage/${username}/answers?size=20&page=${page}&sort=newest`)
.then(v=>v.json())
.then(v=>v.rows)
.then(async v=>{
if(v.length === 20 && (v[v.length - 1]?.created || 0) > startTime){
return v.concat(await getAnswers(username, page + 1, startTime))
}else{
return v.filter(v=>v.created > startTime)
}
})
// .then(console.log)
}
list = [];
getAnswers('linong')
.then(console.log)
// new Date(1655005451 * 1000).toLocaleString();
// new Date('2022-06-01 00:00:00.000').getTime()
僅供學習,不要違法喲!
檢視幾個活躍使用者
await getAnswers('hfhan')
.then(console.log)
await getAnswers('jamesfancy')
.then(console.log)
await getAnswers('nickw_cn')
.then(console.log)
await getAnswers('xdsnet')
.then(console.log)
我們會發現這裡的 username
好像是一個固定值,和使用者名稱是不一樣的,那我們在做一個 url 提取,方便我們不用手動選中
'https://segmentfault.com/u/jamesfancy/answers'.match(/\/u\/([^/]+)/)[1]
分析如何獲取是否有小尾巴
因為不是 graphql 的,所以上述內容只能有多少回答,如果想檢視小尾巴的新增狀況我們還需要再做一次採集。
通過檢視好像也沒有暴露出有介面,那我們只能直接處理 html 資料了。
xhr = new XMLHttpRequest()
xhr.open('get', 'https://segmentfault.com/q/1010000041964562/a-1020000041964682')
xhr.responseType = 'document'
xhr.send();
xhr.onload = () => console.log(xhr.response, xhr.response.querySelector('[id="1020000041964682"] [href^="https://segmentfault.com/a/1190000041925107"]'))
這樣我們使用選擇器直接判斷回答中是否包含特徵值即可,你猜為什麼我這裡用了 xhr,而不是 fetch 呢?
url 提取 id
'https://segmentfault.com/q/1010000041964562/a-1020000041964682'.match(/\/a-(\d+)$/)[1]
改造 迴圈
getAnswers = function(username, page = 1, startTime = new Date('2022-06-01 00:00:00.000').getTime() / 1000){
return fetch(`https://segmentfault.com/gateway/homepage/${username}/answers?size=20&page=${page}&sort=newest`)
.then(v=>v.json())
.then(v=>v.rows)
.then(async v=>{
if(v.length === 20 && (v[v.length - 1]?.created || 0) > startTime){
return v.concat(await getAnswers(username, page + 1, startTime))
}else{
return v.filter(v=>v.created > startTime)
}
})
// .then(console.log)
}
checkAnswerExt = async function(url){
const id = url.match(/\/a-(\d+)$/)[1];
var xhr = new XMLHttpRequest()
xhr.open('get', `https://segmentfault.com${url}`)
xhr.responseType = 'document'
xhr.send();
return new Promise(function(resolve, reject){
xhr.onload = () =>
resolve(
xhr
.response
.querySelector(`[id="${id}"] [href^="https://segmentfault.com/a/1190000041925107"]`)
)
})
}
answers = [];
await getAnswers('cowcomic')
.then(async function(list){
for(var i = 0; i < list.length; i++){
answers.push({
answers: list[i],
checked: await checkAnswerExt(list[i].url)
})
}
})
// .then(console.log)
answers
可以發現,的確是存在沒有小尾巴,這樣補一下即可。
分析資料
這樣我們有了個人問答所有關心的資料,接下來我們可以 groupBy 查出所有沒有小尾巴的資料,然後補一下資料。
也可以按時間維度檢視每天完成量
大功告成。最後再提醒一居,僅供學習,不要違法喲!