一朋友在群里问有没有什么办法能够一次性把这个链接里的文章保存下来。点开可以看的到,其实就是一个文章合集,所以需求就是,把这个文档中的链接里的文章挨个保存下来。保存形式可以有很多种,可以是图片,也可以是网页。这里因为使用操纵库的原因,故选择保存格式格式为PDF。
完成整个动作,主要分为这两个部分。获取文档内所有文章的链接;把每个链接里的内容保存为PDF文件。
对于获取链接,有两条路,一是使用请求模块请求该网址获取文档;二是把网页保存到本地使用fs模块获取文档内容。拿到文档也就是整个HTML文档后,一开始没想到什么好法子来拿到全部文章链接。如果直接在网页那就好办,直接DOM的<代码> quertSelectorAll> 代码API配合CSS选择器就可以非常方便地拿到所有<代码> 代码>链接中的<代码> href 代码>属性。但这里是节点,是DOM外之地。又想到的是直接使用正则匹配,后来还是放弃了这个做法。在谷歌搜了下才发现竟然忘了<代码>好呀> 代码这个好东西。<代码>好呀> 代码是一个专门为服务端设计的快速灵活而简洁得jQuery实现。
对于保存网页内容,我所知道的常规操作是保存为PDF文件,恰巧之前刚知道的<代码>操纵木偶的代码>满足这样的需求。<代码>操纵木偶的代码>是一个由chrome devtools <代码> 代码>团队维护的提供了控制铬浏览器高级API的一个节点库。除去爬取网页内容保存为PDF文件外,它还可以作为服务端渲染的一个方案以及实现自动化测试的一个方案。
<强>获取链接强>
先上这部分代码
const getHref=https://www.yisu.com/zixun/function () { 让文件=fs.readFileSync (。/index . html) .toString () const美元=cheerio.load(文件) 山姆让href=$ (' # '); (' a ') (ein href) { 如果(href [e]。鲜明,,href [e] .attribs [“href”]) { hrefArr.push ({ 指数:e, href: href [e] .attribs (“href”) }) } } fs.writeFileSync (“hrefJson。json, JSON.stringify (hrefArr)) }
因为后面的代码都依赖到读取的文件,所以这里用的是readFileSync方法。如果没有声明返回内容的格式,那默认是缓冲格式。可以选择填写<代码> utf8 代码>格式,或者直接在该方法后面使用<代码> toString 代码>方法。
两行代码用加油拿到所有所有链接的DOM元素后,挨个将其处理为方便后面要用到的格式。考虑到可能存在的标签没有href属性的情况,这里还对其进行了判断,不过这也是后面调试程序时才发现的错误。
如果需要将所有的链接另外保存起来,使用<代码> writeFile 代码>方法。
<强>存为PDF 强>
同样,先上这部分代码。
const saveToPdf=function () { 异步()=比;{ const浏览器=等待puppeteer.launch ({ executablePath:“。/chrome-win/chrome.exe ', });//链接计数 让我=0 异步函数getPage () { const页面=等待browser.newPage (); 等待页面。转到(hrefArr[我](“href”), {waitUntil:“domcontentloaded”内});//网页标题 让pageTitle 如果(hrefArr[我][“href”)其中包括(weixin)) { pageTitle=等待页面。美元eval(“元[属性=柏?标题”],el=比;el.content) 其他}{ pageTitle=等待页面。美元eval(“标题”,el=比;el.innerHTML) } 让标题=pageTitle.trim ()//去掉斜杆 让titlea=标题。替换(/\ s */g, " ")//去掉竖线 让titleb=titlea。替换(/\ |/g, " "); 等待页面。pdf({路径:“${我}$ {titleb}。pdf的}); 我+ + 如果我& lt;hrefArr.length) { getPage () 其他}{ 等待browser.close (); } } getPage () } }
因为需要等待chrome浏览器的打开,以及其他可能的异步请求。最外层使用了异步配合箭头函数将真正的执行代码包住。
在用npm安装<代码>傀儡> 代码时,因为默认会下载chrome浏览器,而服务器在国外,一般都无法下载成功。当然也有相应的解决方案,这里我就不展开了。如果安装<代码>操纵> 代码,可以参开这篇文章或者直接谷歌搜下。
在前一部分说到,我们需要把不止一个链接里的内容保存为PDF,所以使用了变量<代码>我> 代码来标识每一次需要访问的链接。
对于获取网页标题,当时确实费了点时间才处理好拿到已有链接的网页标题,所以链接中主要有两种网站的链接,一类是微信公众号文章,另一类是新浪财新这种网站。微信文章里头没有像新浪这样直接给出标题