获取瀑布流王网页全部内容
问题来自: 求:保存【响应式网页】到本地文件的工具 和 小众论坛上用浏览器自带搜索只能搜到一部分内容 - #16,来自 Betty
先说明,是否有必要保存整个网页这件事情有待商榷,我个人以为这个需求应该是在(资料收集)方法上就出了问题。这个工作已经接近爬虫范畴了,责问网页就有点缘木求鱼吧。但这不妨碍我们技术层面讨论。
获取一个回帖的内容很简单,这里稍微放一张图片
每个 .topic-post
就是一个回帖,但这个元素没啥特征,article
这个元素比较好,包含所有回帖内容,并且它的 id 标记了“楼层”。于是就准备一个对象储存内容,然后遍历一下这个元素:
const data = {}
document.body.querySelectorAll('.topic-post > article').forEach(el=>{
data[el.id] = el.innerHTML
})
好了,但是数量不够,因为网页没加载出来所有帖子,所以我们要让页面往下滚动,然后再获取。先说往下滚动:
while(true){
const Y = window.scrollY
window.scrollTo(0,Y+1000)
// 工作代码放这里
if(Y === window.scrollY) break
}
获取当前滚动的位置,向下滚动 1000 像素,如果位置没变化,那就不滚了,否则无休止的进行下去。兄弟们,虽然这是代码,但它不吃人,你平心静气的思考一下会发现很简单的事情啦。
上下组合一下基本就可以用了,不过严谨点最好判断一下是不是已经保存过某个帖子了,如果是,那就别覆盖了,当然,可能也要判断一下保存的版本文字长度是不是太短之类,我就不详细演示了,简单示例如下:
const data = {}
while(true){
const Y = window.scrollY
window.scrollTo(0,Y+1000)
document.body.querySelectorAll('.topic-post > article').forEach(el=>{
if(data[el.id]) return
data[el.id] = el.innerHTML
})
if(Y === window.scrollY) break
}
核心方法很简单,不过实际使用中要考虑的问题比较多,不展开,就简单说一下:
- 滚动后应该给网页留出加载时间,做一个延时
- 数据量的问题,各种意义上的可能爆内存,遍历太快还可能爆 cpu
至于合并数据,拼接字符串嘛,爆内存就是另外的问题了