puppeteer爬虫教程_python爬虫入门最好书籍

puppeteer爬虫教程_python爬虫入门最好书籍译者按: 本文通过简单的例子介绍如何使用Puppeteer来爬取网页数据,特别是用谷歌开发者工具获取元素选择器值得学习。原文: AGuidetoAutomating&am

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

译者按: 本文通过简单的例子介绍如何使用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行:

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

    const page = await browser.newPage();

  • 第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

puppeteer爬虫教程_python爬虫入门最好书籍

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

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

  

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

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

  

 截屏的效果会更加漂亮。

puppeteer爬虫教程_python爬虫入门最好书籍

下面是最终版本的代码:

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爬虫教程_python爬虫入门最好书籍

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

page.click(selector[, options])

  • selector 一个选择器来指定要点击的元素。如果多个元素满足,那么默认选择第一个。

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



puppeteer爬虫教程_python爬虫入门最好书籍

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



puppeteer爬虫教程_python爬虫入门最好书籍

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

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

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

puppeteer爬虫教程_python爬虫入门最好书籍

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

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

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

puppeteer爬虫教程_python爬虫入门最好书籍

 

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

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

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

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

  价格也可以用相同的方法获取。

  

puppeteer爬虫教程_python爬虫入门最好书籍

 

 

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:进一步优化

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



puppeteer爬虫教程_python爬虫入门最好书籍

提示

和例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!
});

  

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/167491.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 用Java 写一个冒泡排序

    用Java 写一个冒泡排序冒泡排序几乎是个程序员都写得出来,但是面试的时候如何写一个逼格高的冒泡排序却不是每个人都能做到,下面提供一个参考代码:importjava.util.Comparator;/***排序器接口(策略模式:将算法封装到具有共同接口的独立的类中使得它们可以相互替换)*/publicinterfaceSorter{ /** *排序 *@paramlist待排序的数组 */ public<TextendsComparable<T>>voids

    2022年7月7日
    29
  • [.NET | 發佈] 如何指定固定的目錄給程式調用的外部DLL?

    [.NET | 發佈] 如何指定固定的目錄給程式調用的外部DLL?

    2021年8月26日
    57
  • bootstrap分页样式

    bootstrap分页样式bootstrap分页样式在bootstrap.min.css文件中好像没有包含进来bootstrap.css才有的 .pagination{height:40px;margin:20px0;}.paginationul{border-radius:3px3px3px3px;box-shadow:01px2pxrg

    2022年7月17日
    12
  • win7任务管理器快捷键是什么

    win7任务管理器快捷键是什么根据小编的观察与发现,发现有些小伙伴不是因为不使用快捷键,而是不知道任务管理器的快捷键。所以为了帮助这些小伙伴,小编今天就来告诉你们打开任务管理器的快捷键是什么。我们的电脑其实在打开一些应用的时候,是有快捷键的。但是往往都是因为我们不知道快捷键是什么,所以才会没有用。所以今天小编就来告诉你们打开任务管理器的快捷键是什么。方法一:任务管理器打开的快捷键:ctrl+alt…

    2022年6月18日
    38
  • 线程池详解(通俗易懂超级好)「建议收藏」

    线程池详解(通俗易懂超级好)「建议收藏」目标【理解】线程池基本概念【理解】线程池工作原理【掌握】自定义线程池【应用】java内置线程池【应用】使用java内置线程池完成综合案例线程池线程池基础线程池使用线程池综合案例4.学员练习5.线程池总结概念介绍1:什么是线程池2:为什么使用线程池3:线程池有哪些优势什么是池什么是线程池线程池其实就是一种多线程处理形式,处理过程中可以将任务添加到队列中,然后在创建线程后自动启动这些任务。这里的线程就是我们前面学过的线程,这里的任务就是我们前面学过的实现了Runna.

    2025年8月3日
    4
  • 基于matlab的直流电机仿真,基于MATLAB的无刷直流电机控制系统仿真

    基于MATLAB的无刷直流电机控制系统仿真(论文10000字)摘要:本论文主要关注无刷直流电机的调速控制系统,学习此电机的运行原理和PWM控制方法,简述了调速的概念、控制原理与方法、现状,并且学习并使用无刷直流电机的换相控制方法,并对无刷直流电动机调速系统进行设计。并通过Simulink来建模仿真和实验模拟得知电机的运行情况,并且根据仿真结果对无刷直流电机开始学习分析,从而达到对无刷直流电机的转速…

    2022年4月11日
    86

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号