需求分析别人分享了很多网盘链接,自己一个一个手动传输很浪费时间,而且这些操作都是重复劳动。这个功能和Pandownload类似,但是pandownload因为某些原因不能使用,所以只能自己实现。思路其实很简单,就是完全模拟人的操作,保存网盘链接。我们可以把网盘链接分为两种,第一种是不带提取码的,第二种是带提取码的。前者比后者少了一个提交提取码的步骤。那么,我们在访问一个网盘链接时,如何区分是哪一个呢?可以通过访问页面的标题来确定。这种没有提取码,后缀不限。这种需要填写提取码。后缀是请输入提取码。写代码的时候,可以通过截取提取码的最后三个字符来填写cookie信息进行批量转储。前提是我们要登录,我这里实现的方案是直接从浏览器获取cookie信息,复制到代码中使用。查看网站的cookie信息,可以使用插件EditThisCookie点击右上角导出cookie,把cookie粘贴在板子里,复制到代码里,然后循环使用page.setCookie方法将所有的cookie放在当前请求上下文中,填写提取码,等待页面加载,找到输入提取码框的元素,找到它的id。然后使用page.$$eval()方法获取写入一些可以看到的东西,这里的id就是accessCode。所以我们只需要写awaitpage.$$eval('#accessCode',writeCode,code);asyncfunctionwriteCode(nodes,code){for(letnodeofnodes){node.value=code;}}。这里我是直接修改node.value,你也可以使用puppeteer模拟器来填写。ExtractFiles找到ExtractFiles按钮,点击它,等待跳转完成。值得注意的是,我们必须点击A标签,其他标签需要过滤。awaitpage.$$eval('.g-button-blue-large',click);awaitpage.waitFor(1000);asyncfunctionclick(nodes){for(letnodeofnodes){if(node.title==='提取文件'){awaitnode.click();}}}然后等待跳转选择要保存的文件这里简单的实现是选择所有文件,但是值得注意的是,如果是单个文件,是不需要点击选择所有文件的。如图,可以通过判断元素是否存在,是否需要点击来判断是否有复选框,但是这里比较奇怪的是,class的值是一个不可读的字符串。我不确定这个值是否与用户有关,所以这里只是编码。既然我们需要做的就是找到这个元素并点击它,那么我们就可以做到awaitpage.$$eval('.zbyDdwb',selectAll);asyncfunctionselectAll(nodes){for(letnodeofnodes){等待node.click();休息;}}点击保存到网盘和点击解压文件一样,找到目标按钮,然后点击。有兴趣的朋友可以自己试试,在弹出的框中选择保存的文件路径,免得麻烦。这里写起来比较简单。如果有框选择与上次相同,则点击选择与上次相同。如果没有,则直接存放在根目录下。(可以根据自己的需要改)选择之前选择之后,可以发现只有Class的值变了,所以在实现的时候改一下值就可以了。等待页面。$$eval('.save-path-item',chooseLocation);asyncfunctionchooseLocation(nodes){for(letnodeofnodes){node.setAttribute('class','save-path-itemcheck');}}点击确定按钮和前面的按钮一样,我们只需要找到确认按钮并点击即可。等待页面。$$eval('[title=OK]',confirm)asyncfunctionconfirm(nodes){for(letnodeofnodes){console.log(node.tagName);if(node.tagName==='A'){awaitnode.click();}}}这样,整个逻辑就完成了。完整的代码,为了程序能正常运行,还需要添加一些额外的waitFor等待,避免操作过快导致IP封禁、元素卸载等乱七八糟的问题。同时这里的数据全部来自于数据库,所以有更新数据库状态的代码。constPan=require('../model/Pan');const{Cluster}=require('puppeteer-cluster');constcrawler=require('./crawler');constcookies=[];asyncfunctionselectAll(节点){console.log('selectAll',nodes.length);for(letnodeofnodes){awaitnode.click();休息;}}asyncfunctionclick(nodes){console.log('click',nodes.length);for(letnodeofnodes){if(node.title==='提取文件'){awaitnode.click();}}}asyncfunctionwriteCode(nodes,code){console.log('writeCode',nodes.length);for(letnodeofnodes){node.value=code;}}asyncfunctionconfirm(nodes){console.log(nodes.length);for(letnodeofnodes){console.log(node.tagName);if(node.tagName==='A'){awaitnode.click();}}}asyncfunctionclickSave(nodes){for(letnodeofnodes){if(node.tagName==='A'){awaitnode.click();休息;}}}asyncfunctionchooseLocation(nodes){for(letnodeofnodes){node.setAttribute('class','save-path-itemcheck');}}asyncfunctionsaveBaidu(){constcluster=awaitCluster.launch(crawler.clusterLanuchOptionsPan);awaitcluster.task(async({page,data})=>{let{id,url,code}=data;for(leti=0;i
