简介:
cheerio是node.js的抓取页面模块,为服务器特别定制的,快速、灵活、实施的jQuery核心实现。适合各种web爬虫程序。
爬取斗图啦网站图片例子
1 const cheerio = require('cheerio') 2 const axios = require('axios') 3 const fs = require('fs') 4 const path = require('path') 5 // cheerio 获取HTML文档的内容,内容的获取跟jquery一样 6 7 // 起始地址-分析网站结构 8 let httpUrl = "https://www.doutula.com/article/list/?page=1"; 9 10 // 获取页面总数 11 async function getNum() { 12 res = await axios.get(httpUrl) 13 let $ = cheerio.load(res.data) 14 let btnLength = $('.pagination li').length 15 let allNum = $('.pagination li').eq(btnLength - 2).find('a').text() 16 console.log(allNum); 17 return allNum 18 } 19 20 async function spider() { 21 // 获取所有页面的总数 22 let allPageNum = await getNum() 23 for(let i=1;i<= 50;i++) { 24 getListPage(i) 25 } 26 } 27 28 async function getListPage(pageNum) { 29 let httpUrl = "https://www.doutula.com/article/list/?page=" + pageNum; 30 let res = await axios.get(httpUrl) 31 // cheerio解析html文档 32 let $ = cheerio.load(res.data) 33 // 获取当前页面的所有的表情页面的链接 34 $('#home .col-sm-9>a').each((i, element) => { 35 let pageUrl = $(element).attr('href') 36 let title = $(element).find('.random_title').text() 37 let reg = /(.*?)d/igs; 38 title = reg.exec(title)[1] 39 fs.mkdir(`./img/${title}`, (err) => { 40 if (err) { 41 console.log(err); 42 } else { 43 console.log('成功创建目录:' + './img/' + title); 44 } 45 }) 46 parsePage(pageUrl, title) 47 }) 48 } 49 50 async function parsePage(url, title) { 51 let res = await axios.get(url) 52 let $ = cheerio.load(res.data) 53 $('.pic-content img').each((i, element) => { 54 let imgUrl = $(element).attr('src') 55 // 获取扩展名 56 let extName = path.extname(imgUrl) 57 // 图片写入的路径和名字 58 let imgPath = `./img/${title}/${title}-${i}${extName}` 59 // 创建图片可写流 60 let ws = fs.createWriteStream(imgPath) 61 axios.get(imgUrl, { responseType: 'stream' }).then(res => { 62 // 通过管道流入到可写流的来源流 63 res.data.pipe(ws) 64 console.log('图片加载完成:', imgPath); 65 // res.data.on('close',() => { 66 // ws.close() 67 // }) 68 }) 69 }) 70 } 71 spider()
爬取音乐网站下载音乐:
1 // 目标:下载音乐 2 // 1获取音乐相关的信息,通过音乐相关的信息获取mp3地址 3 // 2如何获取大量的音乐信息,通过获取音乐列表 4 // 3通过音乐的分类页,获取音乐列表 5 6 const axios = require('axios') 7 const fs = require('fs') 8 const path = require('path') 9 10 // 获取音乐 11 async function getPage(num) { 12 let httpUrl = "http://www.app-echo.com/api/recommend/sound-day?page=" + num 13 let res = await axios.get(httpUrl) 14 15 res.data.list.forEach((item, i) => { 16 let title = item.sound.name 17 let mp3Url = item.sound.source 18 let filename = path.parse(mp3Url).name 19 20 let content = `${title},${mp3Url},${filename} ` 21 fs.writeFile('music.txt', content, {flag:'a'},() => { 22 console.log('写入完成:'+ title); 23 }) 24 // console.log(title); 25 // console.log(mp3Url); 26 download(mp3Url,filename) 27 }) 28 } 29 30 // 下载音乐 31 async function download(mp3Url, filename) { 32 let res = await axios.get(mp3Url, { responseType: "stream" }) 33 // 创建可写流 34 let ws = fs.createWriteStream('./mp3/' + filename + '.mp3') 35 // 通过管道流入到可写流的来源流 36 res.data.pipe(ws) 37 // res.data.on('close',() => { 38 // ws.close() 39 // }) 40 } 41 42 for(i=1;i<=5; i++) { 43 getPage(i) 44 }
Puppeteer
出现的背景
Chrome59(linux、macos)、Chrome60(windows)之后,Chrome自带headless(无界面)模式很方便做自动化测试或者爬虫。但是如何和headless模式的Chrome交互则是一个问题。通过启动Chrome时的命令参行参仅能实现简易的启动时初始化操作。Selenium、Webdriver等是一种解决方案,但是往往依赖众多,不够扁平。
Puppteer是谷歌官方出品的一个通过DevTools协议控制headless Chrome的库。通过Puppeteer的提供api直接控制Chrome模拟大部分用户操作来进行UI Test或者作为爬虫访问页面来收集数据。
作用:
-
生成页面的屏幕截图和PDF。
-
爬取SPA(单页应用程序)并生成预渲染的内容(即“ SSR”(服务器端渲染))。
-
自动化表单提交,UI测试,键盘输入等。
-
创建最新的自动化测试环境。使用最新的JavaScript和浏览器功能,直接在最新版本的Chrome中运行测试。
-
捕获站点的
-
测试Chrome扩展程序。
使用和例子
Puppeteer类似其他框架,通过操作Browser实例来操作浏览器做出相应的反应。
1 const puppeteer = require('puppeteer') 2 3 (async () => { 4 const browser = await puppeteer.launch(); 5 const page = await browser.newPage(); 6 await page.to('http://rennaiqian.com'); 7 await page.screenshot({path:'example.png'}); 8 await page.pdf({path:'example.pdf',format:'A4'}); 9 await browser.close() 10 })()
上述代码通过puppeteer的launch方法生成了一个browser的实例,对应于浏览器,launch方法可以传入配置选项,比较有用的是在本地调试时传入{headless:false}
可以关闭headless模式。
1 const browser = await puppeteer.launch({headless: false})
browser.newPage方法可以打开一个新选项卡并返回选项卡的实例page,通过page上的各种方法可以对页面进行常用操作。上述代码就进行了截屏和打印pdf的操作。
爬虫总结
1.爬虫介绍
通过模拟浏览器的请求,服务器根据我们的请求返回我们想要的数据,将数据解析出来,并且进行保存
2.爬虫流程
1-目标:确定你想要获取的数据
-
确定想要的数据在什么页面
-
确定在哪些页面可以链接到这些页面
-
寻找页面之间和数据之间的规律
2-分析页面
-
获取数据的方法(正则,cherrio)
-
分析数据是通过ajax请求的数据,还是html里自带的数据
-
如果是通过AjAX请求的数据,那么需要获取ajax请求的链接,一般请求到的数据都为JSON格式数据,那么就容易解析
-
如果数据在HTML里面,那么就用cherrio通过选择器将内容选中
3-编写单个数据获取的案例
-
解析出分类页的链接地址
-
解析出列表页的链接地址
-
解析出详情页的链接地址
-
解析详情页里面想要获取的数据
-
将数据进行保存到本地或者是数据库
4-如果遇到阻碍进行反爬虫对抗
-
User-Agent是否是正常浏览器的信息
-
将请求头设置成跟浏览器一样的内容
-
因为爬虫的爬取速度过快,会导致封ip。1那么可以降低速度进行解决,2可以使用代理进行解决
-
如果设置需要凭证,那么可以采用无界面浏览器真实模拟。
3.请求数据的库
request,axiso:通过库,帮助我们快速实现HTTP请求包的打包
1 request.get('请求地址', { 2 '请求头字段':'请求头的value值' 3 },(res) => { 处理返回的内容 })
axios优势会更明显,前后端通杀,前后端调用方式一致
axios.get('请求地址', 参数对象).then((res) => {
console.log(res)
})
axios获取图片
1 axios({ 2 method: 'get', 3 url: 'http://bit.ly/2mTM3ny', 4 responseType: 'stream' 5 }) 6 .then((res) => { 7 res.data.pipe(fs.createWriteStream('ada_lovelace.jpg')) 8 })
puppeteer:完全模拟浏览器
打开浏览器
1 let options = { 2 headless: true, // 是否是无界面浏览器 3 slowMo: 250, // 调试时可以减慢操作速度 4 defaultViewport: { //设置视宽的宽高 5 1200 6 height: 800 7 }, 8 timeout: 3000, // 默认超时时间3秒 9 } 10 let browser = await puppeteer.launch(options)
打开新标签页
1 let page = await borwser.newPage()
获取所有浏览器中的页面
1 let page = await browser.pages()
关闭浏览器
1 borwser.close()
将页面跳转至
1 await page.goto(url)
获取页面的对象并进行操作
1 let btn = await page.$(selector) 2 let input = await page.$(selector) 3 // 点击按钮 4 btn.click() 5 // 聚焦到输入框 6 input.forcus()
在页面上写入内容或者键盘按键
1 await page.keyboard.type('hello World!'); 2 await page.keyboard.press('ArrowLeft'); 3 await page.keyboard.down('Shift');
截获页面请求
1 await page.setRequestInterception(true) 2 page.on('request', request => { 3 // request 包含请求的所有信息 4 if(你想要的条件) { 5 request.continue() 6 } else { 7 request.respond({ 8 status: 404, 9 contentType: 'text/plain', 10 body: 'Not Found!' 11 }) 12 } 13 })
获取浏览器的信息和内容
1 page.$eval(selector, (item) => { return item }) 2 page.$$eval(selector, (item) => { return item })
Demo
GitHub上有:
更多爬虫相关小案例,欢迎进入