puppeteer之爬虫入门(代码片段)

fundebug fundebug     2023-01-26     624

关键词:

译者按: 本文通过简单的例子介绍如何使用Puppeteer来爬取网页数据,特别是用谷歌开发者工具获取元素选择器值得学习。

为了保证可读性,本文采用意译而非直译。另外,本文版权归原作者所有,翻译仅用于学习。

技术分享图片

我们将会学到什么?

在这篇文章,你讲会学到如何使用JavaScript自动化抓取网页里面感兴趣的内容。我们将会使用Puppeteer,Puppeteer是一个Node库,提供接口来控制headless Chrome。Headless Chrome是一种不使用Chrome来运行Chrome浏览器的方式。

如果你不知道Puppeteer,也不了解headless Chrome,那么你只要知道我们将要编写JavaScript代码来自动化控制Chrome就行。

准备工作

你需要安装版本8以上的Node,你可以在这里找到安装方法。确保选择Current版本,因为它是8+。

当你将Node安装好以后,创建一个新的文件夹,将Puppeteer安装在该文件夹下。

npm install --save puppeteer

例1:截屏

当你把Puppeteer安装好了以后,我们来尝试第一个简单的例子。这个例子来自于Puppeteer文档(稍微改动)。我们编写的代码将会把你要访问的网页截屏并保存为png文件。

首先,创建一个test.js文件,并编写如下代码。

const puppeteer = require(‘puppeteer‘);

async function getPic() 
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto(‘https://google.com‘);
  await page.screenshot(path: ‘google.png‘);

  await browser.close();


getPic();

我们来一行一行理解一下代码的含义。

  • 第1行:引入我们需要的库Puppeteer;
  • 第3-10行:主函数getPic()包含了所有的自动化代码;
  • 第12行:调用getPic()函数。

这里需要提醒注意getPic()函数是一个async函数,使用了ES 2017 async/await特性。该函数是一个异步函数,会返回一个Promise。如果async最终顺利返回值,Promise则可以顺利reslove,得到结果;否则将会reject一个错误。

因为我们使用了async函数,我们使用await来暂停函数的执行,直到Promise返回。

接下来我们深入理解一下getPic()

  • 第4行:

      const broswer = await puppeteer.launch();

    这行代码启动puppeteer,我们实际上启动了一个Chrome实例,并且和我们声明的browser变量绑定起来。因为我们使用了await关键字,该函数会暂停直到Promise完全被解析。也就是说成功创建Chrome实例或则报错。

  • 第5行:

      const page = await browser.newPage();

    我们在浏览器中创建一个新的页面,通过使用await关键字来等待页面成功创建。

  • 第6行:

      await page.goto(‘https://google.com‘);

    使用page.goto()打开谷歌首页。

  • 第7行:

       await page.screenshot(path: ‘google.png‘);

    调用screenshot()函数将当前页面截屏。

  • 第9行:

       await browser.close();

    将浏览器关闭。

执行实例

使用Node执行:

  node test.js

下面截取的图片google.png

技术分享图片

现在我们来使用non-headless模式试试。将第4行代码改为:

  const browser = await puppeteer.launch(headless: false);

然后运行试试。你会发现谷歌浏览器打开了,并且导航到了谷歌搜索页面。但是截屏没有居中,我们可以调节一下页面的大小配置。

await page.setViewport(width: 1000, height: 500);

截屏的效果会更加漂亮。

技术分享图片

下面是最终版本的代码:

const puppeteer = require(‘puppeteer‘);

async function getPic() 
  const browser = await puppeteer.launch(headless: false);
  const page = await browser.newPage();
  await page.goto(‘https://google.com‘);
  await page.setViewport(width: 1000, height: 500)
  await page.screenshot(path: ‘google.png‘);

  await browser.close();


getPic();

例2:爬取数据

首先,了解一下Puppeteer的API。文档提供了非常丰富的方法不仅支持在网页上点击,而且可以填写表单,读取数据。

接下来我们会爬取Books to Scrape,这是一个伪造的网上书店专门用来练习爬取数据。

在当前目录下,我们创建一个scrape.js文件,输入如下代码:

const puppeteer = require(‘puppeteer‘);

let scrape = async () => 
  // 爬取数据的代码
  
  // 返回数据
;

scrape().then((value) => 
    console.log(value); // 成功!
);

第一步:基本配置

我们首先创建一个浏览器实例,打开一个新页面,并且导航到要爬取数据的页面。

let scrape = async () => 
  const browser = await puppeteer.launch(headless: false);
  const page = await browser.newPage();
  await page.goto(‘http://books.toscrape.com/‘);
  await page.waitFor(1000);
  // Scrape
  browser.close();
  return result;
;

注意其中有一行代码让浏览器延时关闭。这行代码本来是不需要的,主要是方便查看页面是否完全加载。

await page.waitFor(1000);

第二步:抓取数据

我们接下来要选择页面上的第一本书,然后获取它的标题和价格。

技术分享图片

查看Puppeteer API,可以找到定义点击的函数:

page.click(selector[, options])

  • selector

幸运的是,谷歌开发者工具提供一个可以快速找到选择器元素的方法。在图片上方右击,选择检查(Inspect)选项。

技术分享图片

谷歌开发者工具的Elements界面会打开,并且选定部分对应的代码会高亮。右击左侧的三个点,选择拷贝(Copy),然后选择拷贝选择器(Copy selector)。

技术分享图片

接下来将拷贝的选择器插入到函数中。

await page.click(‘#default > div > div > div > div > section > div:nth-child(2) > ol > li:nth-child(1) > article > div.image_container > a > img‘);

加入了点击事件的代码执行后会直接跳转到详细介绍这本书的页面。而我们则关心它的标题和价格部分。

技术分享图片

为了获取它们,我们首选需要使用page.evaluate()函数。该函数可以让我们使用内置的DOM选择器,比如querySelector()

const result = await page.evaluate(() => 
// return something
);

然后,我们使用类似的手段获取标题的选择器。

技术分享图片

使用如下代码可以获取该元素:

let title = document.querySelector(‘h1‘);

但是,我们真正想要的是里面的文本文字。因此,通过.innerText来获取。

let title = document.querySelector(‘h1‘).innerText;

价格也可以用相同的方法获取。
技术分享图片

let price = document.querySelector(‘.price_color‘).innerText;

最终,将它们一起返回,完整代码如下:

const result = await page.evaluate(() => 
  let title = document.querySelector(‘h1‘).innerText;
  let price = document.querySelector(‘.price_color‘).innerText;
return 
  title,
  price

);

所有的代码整合到一起,如下:

const puppeteer = require(‘puppeteer‘);

let scrape = async () => 
    const browser = await puppeteer.launch(headless: false);
    const page = await browser.newPage();

    await page.goto(‘http://books.toscrape.com/‘);
    await page.click(‘#default > div > div > div > div > section > div:nth-child(2) > ol > li:nth-child(1) > article > div.image_container > a > img‘);
    await page.waitFor(1000);

    const result = await page.evaluate(() => 
        let title = document.querySelector(‘h1‘).innerText;
        let price = document.querySelector(‘.price_color‘).innerText;

        return 
            title,
            price
        

    );

    browser.close();
    return result;
;

scrape().then((value) => 
    console.log(value); // Success!
);

运行node scrape.js即可返回数据

 title: ‘A Light in the Attic‘, price: ‘£51.77‘ 

例3:进一步优化

从主页获取所有书籍的标题和价格,然后将它们返回。

技术分享图片

提示

和例2的区别在于我们需要用一个循环来获取所有书籍的信息。

const result = await page.evaluate(() => 
  let data = []; // Create an empty array
  let elements = document.querySelectorAll(‘xxx‘); // 获取所有书籍元素 
  // 循环处理每一个元素
    // 获取标题
    // 获取价格
    data.push(title, price); // 将结果存入数组
  return data; // 返回数据
);

解法

const puppeteer = require(‘puppeteer‘);

let scrape = async () => 
    const browser = await puppeteer.launch(headless: false);
    const page = await browser.newPage();

    await page.goto(‘http://books.toscrape.com/‘);

    const result = await page.evaluate(() => 
        let data = []; // 初始化空数组来存储数据
        let elements = document.querySelectorAll(‘.product_pod‘); // 获取所有书籍元素

        for (var element of elements) // 循环
            let title = element.childNodes[5].innerText; // 获取标题
            let price = element.childNodes[7].children[0].innerText; // 获取价格

            data.push(title, price); // 存入数组
        

        return data; // 返回数据
    );

    browser.close();
    return result;
;

scrape().then((value) => 
    console.log(value); // Success!
);

关于Fundebug

Fundebug专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了7亿+错误事件,得到了Google、360、金山软件、百姓网等众多知名用户的认可。欢迎免费试用!

技术分享图片

版权声明

转载时请注明作者Fundebug以及本文地址:
https://blog.fundebug.com/2017/11/01/guide-to-automating-scraping-the-web-with-js



0基础学爬虫爬虫基础之自动化工具pyppeteer的使用(代码片段)

...用到了stealth.min.js文件。在介绍文件的来源时我们提到了Puppeteer,Puppeteer是一个基于Node.js的自动化工具。而这期要将的Pyppeteer就是Puppeteer的Python版。Pyppeteer是一个使用Python语言封装的GoogleChrome浏览器的非官方API。它可以用来进行... 查看详情

puppeteer之大屏批量截图(代码片段)

...一定要最新的数据。所以我就自告奋勇研究了一下。????puppeteer是一款headless浏览器,由谷歌官方维护。先看看puppeteer入门。思路是先打开所有链接,然后设置最长的等待时间,最后进行截图。(13版本puppeteer跟前一版api有挺多不... 查看详情

puppeteer入门与实战(代码片段)

...:https://mp.weixin.qq.com/s/P-YdQPOQ9GZgjDEP7VG8ag作者:WangZhenzhengPuppeteer是Chrome开发团队2017年发布的一个Node.js包,提供了一组用来操纵Chrome的API,通俗来说就是一个HeadlessChrome浏览器,这HeadlessChrome也可以配置成有UI的。利 查看详情

puppet之入门实验学习

    由于在使用openstack自动化部署工具mirantisfuel的过程中,老是出现一些无缘无故的失败,比如我使用fuel9安装mitaka版本openstack的时候,正常安装3节点(1个controller、1个compute、1个cinder)、5节点HA(3个controller、1个c... 查看详情

爬虫-scrapy框架简介与入门(代码片段)

...量,用户只需要定制开发几个模块就可以轻松的实现一个爬虫,用来抓取网页内容以及各种图片,非常之方便。Scrapy使用了Twisted[‘tw?st?d](其主要对手是Tornado)异步网络框架来处理网络通讯,可以加快我们的下载速度,不用自己... 查看详情

自动化运维三贱客之puppet安装(代码片段)

Puppet简介puppet是一种Linux、Unix、windows平台的集中配置管理系统,使用自有的puppet描述语言,可管理配置文件、用户、cron任务、软件包、系统服务等。puppet把这些系统实体称之为资源,puppet的设计目标是简化对这些资源的管理以... 查看详情

puppet工作原理之模块使用(代码片段)

...,这种机制就是模块,有助于结构化、层次化的方式使用puppet,puppet则基于模块自动装载器    从另一个角度来说,模块实际就是按约定的预约定的结构存放了多个我呢见或子目录,目录里的这些文件或子目录必须遵循命令... 查看详情

爬虫puppeteer(代码片段)

github安装npmipuppeteer--registry=https://registry.npm.taobao.org//如果安装出错则可能是因为默认下载了安装包,禁止掉就好了,自己下载会比较快//win设置环境变量setPUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true//下载地址constdownloadURLs=linux:‘https://storage.goo... 查看详情

python爬虫从入门到放弃(十三)之scrapy框架的命令行详解(代码片段)

...0.html这篇文章主要是对的scrapy命令行使用的一个介绍创建爬虫项目scrapystartproject项目名例子如下:localhost:spiderzhaofan$scrapystartprojecttest1NewScrapyproject‘test1‘,usingtemplatedirectory‘/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-pa... 查看详情

爬虫puppeteer登陆企查查(代码片段)

...高(canvas绘制)、滑动过程中坐标轴的变化等信息。使用puppeteer能很好的模拟页面中的事件,但是在进行测试企查查登陆时,需要浏览器的可见性,而且与分辨率也有一定的关系,需要设置浏览器和系统的分辨率为100%,否则会... 查看详情

爬虫入门(代码片段)

爬虫简单的说网络爬虫(Webcrawler)也叫做网络铲(Webscraper)、网络蜘蛛(Webspider),其行为一般是先“爬”到对应的网页上,再把需要的信息“铲”下来。分类网络爬虫按照系统结构和实现技术,大致可以分为以下几种类型:... 查看详情

python爬虫入门(代码片段)

python爬虫入门(3)​BeautifulSoup库入门文章目录python爬虫入门(3)1.安装及测试安装测验2.BeautifulSoup库基本元素①html标签②库的引用③BeautifulSoup类BeautifulSoup库解析器BeautifulSoup类的基本元素获取Tag获取Name获取Attributes获取NavigableString获... 查看详情

如何入门爬虫(基础篇)

一、爬虫入门Python爬虫入门一之综述Python爬虫入门二之爬虫基础了解Python爬虫入门三之Urllib库的基本使用Python爬虫入门四之Urllib库的高级用法Python爬虫入门五之URLError异常处理Python爬虫入门六之Cookie的使用Python爬虫入门七之正则... 查看详情

requests库入门之小爬虫

通用代码框架:try:r=requests.get(url,timeout=30)r.raise_for_status()r.encoding=r.apparent_encodingreturnr.textexcept:return"产生异常" 爬取某网页100次花费的时间importrequestsimporttimedefgetHTMLText(url):try:r=requests 查看详情

python爬虫入门(代码片段)

python爬虫入门(8)​Xpath语法入门​Xpath用于在XML文档中搜索内容​html是xml中的一个子集文章目录python爬虫入门(8)一.Xpath简介1.何为Xpath2.Xpath解析原理3.Xpath语法二.示例1.XML2.HTML一.Xpath简介​准备工作:​pipinstalllxml​lxml是一种... 查看详情

python爬虫入门(代码片段)

python爬虫入门(9)​XPath实战​爬取猪八戒网信息​猪八戒网是服务类电子商务交易平台,提供围绕中小微企业发展的一站式服务文章目录python爬虫入门(9)一.逐步实现1.查看页面源代码2.提取页面源代码3.生成etree对象4.得到XPath... 查看详情

如何入门爬虫(基础篇)

一、爬虫入门Python爬虫入门一之综述Python爬虫入门二之爬虫基础了解Python爬虫入门三之Urllib库的基本使用Python爬虫入门四之Urllib库的高级用法Python爬虫入门五之URLError异常处理Python爬虫入门六之Cookie的使用Python爬虫入门七之正则... 查看详情

java爬虫入门(代码片段)

通用网络爬虫又称全网爬虫(ScalableWebCrawler),爬行对象从一些种子URL扩充到整个Web,主要为门户站点搜索引擎和大型Web服务提供商采集数据。今天我写的主要是一些皮毛入门现在来看下我们的pom依赖 <projectxmlns="http://maven... 查看详情