博客
电影
宝箱
友链
关于
<
读《荷马史诗·伊利亚特》,英雄与命运
读《少年维特的烦恼》与《亲合力》
>
Puppeteer爬取豆瓣电影TOP250评分
作者:
Cifer
类别: 技术·JS
时间:2019-06-17 10:31:31
字数:2326
版权所有,未经允许,请勿转载,谢谢合作~
Puppeteer是Google Chrome headless的官方高级api实现,它可以配置化的模拟Chrome操作,实现截图、爬虫、UI自动测试、诊断网站性能等功能,出于学习的需要,此处用到它写<a href="https://www.boatsky.com/blog/80">一个爬取豆瓣电影TOP250评分的实例</a>,相比于别的爬虫Puppeteer有什么不同呢? 它可以配置headless: false,自动真实的打开本地的Chrome进行的操作,类似于玩游戏的按钮精灵,对于被爬取的服务端来说,它不是爬虫,而是真实的用户。举例,一般爬虫服务器爬取一个网页时,获取到常常是一个html,如它是js渲染的单页面,则不能直接解析html的内容。 豆瓣部分页面就是这种情况,html甚至没有body,而Puppeteer则用最简单的方式解决这个问题,Puppeteer看到的东西与真实用户看到的是一样的。 #### 准备 这本文为例,Cifer这里先设置一个预期目标,爬取电影的链接、名字、评分,同时,为便于扩展方便未来获取更多信息,这些内容最终从“详情页”获取而不从“列表页”直接获取。然后把这些内容转成json保存成一个叫db250.txt文件里。 环境:node版本v10.15.3 Puppeteer文档 <a href="https://pptr.dev" target="_blank">https://pptr.dev</a> 安装puppeteer与fs包 ``` npm install puppeteer npm install fs ``` #### 分析 豆瓣电影TOP250“列表页”是<a href="https://movie.douban.com/top250?start=${i}&filter=" target="_blank">https://movie.douban.com/top250?start=${i}&filter=</a> 其中${i}起始位置,每页25条,所以${i}取值于[0,250],每次递增25,分别获取到页面各部电影的“详情页”链接并临时保存成Array,使用该Array分别爬取详情页面,获取名字、评分及已知的链接保存起来。 #### 实现, db250.js ```javascript const puppeteer = require('puppeteer'); const fs = require('fs'); let movieLinkArr = []; let movieArr = []; start(); // 开始 async function start() { await puppeteer.launch({ headless: false,// 关闭无图形爬取,进行真实的模拟 }).then(async browser => { const page = await browser.newPage(); for (let i = 0; i < 250;i = i + 25) { await getDoubanLink(page, i); } for (let j = 0; j < movieLinkArr.length; j++) { await gotoDetail(page, movieLinkArr[j]); } fs.writeFile('db250.txt', JSON.stringify(movieArr), () => console.log('当前目录,文件db250.txt生成成功')); await page.close(); await browser.close(); }); } // 获取豆瓣250链接 async function getDoubanLink(page, i) { await page.goto(`https://movie.douban.com/top250?start=${i}&filter=`); let pageArr = await page.$$eval('.item .hd a', elArr => { let arr = []; elArr.forEach(el => { arr.push(el.getAttribute('href')); }); return arr; }); movieLinkArr = movieLinkArr.concat(pageArr) } // 详情页 async function gotoDetail(page, link) { await page.goto(link); const name = await page.$eval('span[property="v:itemreviewed"]', el => el.innerText); const rate = await page.$eval('.ll.rating_num', el => Number.parseFloat(el.innerText)); const obj = { name, rate, link, }; movieArr.push(obj); console.log(`抓取成功=> ${obj}`); } ``` 开始执行 ``` node db250 ``` 查看命令行提示,几分钟之后,在当前目录,可以看到生成的db250.txt。 因为爬取数据很少,没遇到反爬虫的限制,如爬取数据较多,则可以在中间加入随机的时间间隔,并使用IP代理池,表现的更像一个用户。
如果觉得有帮忙,您可以在本页底部留言。
相关推荐:
NPM发包流程与技巧
基于vue实现腾讯云点播的上传与播放
JS代理Proxy与反射Reflect场景
轻应用PWA实践全过程
ES6迭代器Iterator原理与性能
JavaScript之Set与Map
ES6设计模式之观察者模式
解决toFixed四舍五入陷阱
深入理解IEEE754的64位双精度
ES6设计模式之单例模式
ES6设计模式之工厂模式
ES6二叉树的实现
JavaScript链表实例
JavaScript排序算法及性能比较
原生ajax及jQuery封装ajax实例
JavaScript类的语法糖
……
更多
<
读《荷马史诗·伊利亚特》,英雄与命运
读《少年维特的烦恼》与《亲合力》
>
全部留言
我要留言
内容:
网名:
邮箱:
个人网站:
发表
全部留言