Node笔记六(爬虫初涉)

爬虫
  • 爬虫是按照一定规则自动抓取网络信息的程序
  • 爬虫也就是通过插件模仿用户操作来提取html页面上面的数据
反爬虫
  • User-Agent,Referer,验证码
  • 单位时间访问次数,访问量
  • 关键信息图片混淆
  • 异步加载
初始用爬虫截取百度图片(puppeteer)
  • 附上puppeteer的API链接 puppeteerAPI
  • 使用puppeteer的时候要注意 因为被墙 所以 要使用cnpm下载
  • puppeteer.js
const puppeteer = require('puppeteer');//引入模块
const { screenshot } = require('./config/default.js'); //引入路径文件
(async()=>{
    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    await page.goto('http://www.baidu.com',{waitUntil:'networkidle2'});//打开网址
    await page.pdf({
        path:`${screenshot}/${Date.now()}.pdf`,//截图保存的路径如果要存png把pdf改为png把fomat,waitUntil删除
        format: 'A4'
    })
    await browser.close();//关闭网站
})()
  • config/default.js
const path = require('path');
module.exports = {
  screenshot:path.resolve(__dirname,'../../screenshot')
};

使用爬虫爬取百度图片并区分出图片的url和base64
  • default.js设置输出绝对路径
const path = require('path');
module.exports = {
  screenshot:path.resolve(__dirname,'../../screenshot'),
  mn:path.resolve(__dirname,'../../mn')
};
  • srctoimg.js处理图片的base64格式与http格式并存到本地路径
const http = require('http');
const https = require('https');
const fs = require('fs');
const path = require('path');
const { promisify } = require('util');//给callpack转成promise形式
const writeFile = promisify(fs.writeFile);//把写文件也转化为promise的形式

module.exports = async (src,dir)=>{//通过传递过来的src来判断到底是url还是base64的 不同的调用不同的方法
    if(/\.(jpg|png|gif)$/.test(src)){
        await urlToImg(src,dir);
    }else {
        await base64ToImg(src,dir);
    }
}

const urlToImg = promisify((url,dir,callback) =>{
    //如果是url来判断下是http的还是https的
    const mod = /^https:/.test(url)?https:http;//选择正确的模块 
    const ext = path.extname(url);//拿到拓展名
    const file = path.join(dir,`${Date.now()}${ext}`);//文件夹+时间戳+拓展名
    
    mod.get(url,res=>{ //有了url通过get 拿到res响应
        res.pipe(fs.createWriteStream(file))//把响应pipe到了fs创建的一个可写流里面
        .on('finish',() =>{ //对可写流进行操作 因为咱们里面都是用的acync await的这
            //突然一个callback()所以通过promisify来转化为promise的这样async就可以处理了
            callback();
            console.log(file)
        })
    })
})

//base 64 => image

const base64ToImg = async function (base64Str, dir) {
    //data:image/jpeg;base64,/asdasda
    const matches = base64Str.match(/^data:(.+?);base64,(.+)$/);
    //以data:开头然后任意字符加?是遇到第一个;就停下来否则正则默认贪婪模式 会一直往后匹配
    try{
        const ext = matches[1].split('/')[1].replace('jpeg','jpg');
        const file = path.join(dir,`${Date.now()}.${ext}`);
        await writeFile(file,content,'base64');//因为writefile也是callback风格的所以promisify先转化 然后就可以用await调用了
    }catch(ex){

    }

}


  • puppeteer.js 写爬虫模拟用户操作逻辑
const puppeteer = require('puppeteer');//引入模块
const { mn } = require('./config/default.js'); //引入路径文件
const srctoimg = require('./helper/srctoimg.js')
let foo = async ()=>{
    const browser = await puppeteer.launch({headless: false});//这里加上false可以看到页面运行过程
    const page = await browser.newPage();
    await page.goto('http://www.baidu.com/');//打开网址
    //通过改变浏览器窗口的大小来一次性加载多张图片 还有一种可以触发滚动条触发懒加载
    await page.setViewport({
        width:1920,
        height:1080
    })
    //模拟真人操作
    //1.焦点输入
    //2.键盘输入
    await page.focus('#kw')//#kw是百度首页输入框的ID模拟焦点聚焦到输入框
    await page.keyboard.sendCharacter('狗');//模拟键盘输入狗
    await page.click('#su')//这个是模拟点击百度一下
    await page.waitFor(1000);
        const srcs = await page.evaluate(()=>{
            const images = document.querySelectorAll('img');//根据img标签找出所有的img里面的src的集合
            return Array.prototype.map.call(images,img => img.src);//不能直接使用map找因为images没有map方法
        });
    await browser.close();//关闭网站
    return srcs
}
foo().then((value)=>{
    value.forEach(item=>{
        srctoimg(item,mn)
    })
})
  • 完善的爬虫应该是 抓取数据 数据入库 启动服务 渲染数据
如果想要深入学习node.js可以了解下
  • Stream
  • 动态Web framework
  • child_process & cluster
  • through2
  • Express、koa、egg
  • SSR & 同构
  • NodeJS 源码

你可能感兴趣的:(node.js)