已参加了 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"]`)
)
})
}
list = [];
getAnswers('cowcomic')
.then(async function(list){for(var i = 0; i < list.length; i++){// console.log(i, list[i], list[i].url, await checkAnswerExt(list[i].url))
list.push({answers: list[i],
checked: await checkAnswerExt(list[i].url)
})
}
})
// .then(console.log)