已参与了 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 查出所有没有小尾巴的数据,然后补一下数据。
也可以按时间维度查看每天完成量
大功告成。最后再提醒一居,仅供学习,不要违法哟!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。