已参加了 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)