使用Puppeteer进行数据抓取(三)——简单的示例

本文以一个示例简单的介绍一下puppeteer的用法,我们的目的是:获取我博客上的文章的前十页的所有随笔的标题和链接。由于puppeteer本身是自动化chorme,因此这里我们的步骤和手动操作浏览器差不多:

  1. 打开chrome,跳转到博客首页
  2. 获取所有博客标题信息
  3. 点击下一页按钮,跳转到下一页
  4. 重复2、3两步,直到所有信息采集完毕

获取信息

采集过程中比较麻烦的一步就是信息的采集,和传统采集html后解析的方式不同的时,由于chrome本身有完整的js引擎,因此我们采用注入一段js,利用该js采集到我们的信息,并通过puppeteer返回给应用程序的方式。由于puppete本身是采用的chrome,因此编写采集信息函数这一过程完全可以在chrome上进行。

首先用chrome打开我的博客的首页http://www.cnblogs.com/TianFang/,打开chrome devtool,获取标题的css path。然后我们可以利用chrome的snippets简单的写一个获取所有标题信息的函数:

  

本身就蜘蛛程序而言,编写获取脚本内容的这个部分是比较繁琐的,需要不断的反复调试。但使用snippets直接编写函数大大简化了这一过程,它的主要好处有:

  1. 可以直接使用各种js函数,可以直接操作各种dom对象
  2. 利用snippets编写可以在chrome中实时调试,
  3. 可以实时查看生成结果

然后我们只需要将这个函数放到node中,利用puppeteer跳转到相应的页面,使用page.evaluate函数执行这个函数即可。

async function getTitles() {
    var titles = $(‘.postTitle>a‘);

var result = titles.map((i, a) => ({
        text: a.text,
        href: a.href
    })).get();

console.table(result);
    return result;
}

var titles = await page.evaluate(getTitles);
console.log(titles);

一个需要注意的地方是,这个函数实际上是在chrome中执行的,puppeteer要求在chrome中执行的函数必须是异步的,因此需要加上async关键字。

页面跳转

下一步需要解决的问题就是如何跳转到下一页了。方法也比较简单:分析一下页面,找到下一页的连接,执行js模拟点击即可:

page.evaluate(async() => $(`a:contains(‘下一页‘)`)[0].click());

完整代码如下:

const puppeteer = require(‘puppeteer‘);

const chrome_exe = String.raw`${process.env["ProgramFiles(x86)"]}\Google\Chrome\Application\chrome.exe`;
const user_data_path = String.raw`${process.env.LocalAppData}\Google\Chrome\User Data\Default`;

async function run() {
    const browser = await puppeteer.launch({
        headless: false,
        userDataDir: user_data_path,
        executablePath: chrome_exe
    });
    const page = await browser.newPage();
    page.setViewport({ width: 1600, height: 900 });
    await page.goto(‘http://www.cnblogs.com/TianFang‘);

for (var i = 0; i < 10; i++) {

console.log(i);
        console.log(page.url());

var titles = await page.evaluate(getTitles);
        console.log(titles);

await page.evaluate(async() => $(`a:contains(‘下一页‘)`)[0].click());
        await page.waitForNavigation();

await sleep(1000);
    }
};

async function getTitles() {
    var titles = $(‘.postTitle>a‘);

var result = titles.map((i, a) => ({
        text: a.text,
        href: a.href
    })).get();

console.table(result);
    return result;
}

async function sleep(timeout) {
    return new Promise(resolve => setTimeout(resolve, timeout));
}

run();

整个过程还是非常简单的, 执行结果如下:

  

另外值得一提的是,细心的朋友可能注意到这里我们编写一个可以await的sleep函数。

async function sleep(timeout) {
    return new Promise(resolve => setTimeout(resolve, timeout));
}

这个函数本身不是必须的,但在编写蜘蛛程序过程中却经常需要等待的,使用await异步等待可以大大提高代码的可读性,由于node本身没有提供可以await的sleep函数。并且这个函数非常实用,这里就自己实现了一个,记录一下,以备以后使用。

原文地址:https://www.cnblogs.com/TianFang/p/9060309.html

时间: 2024-10-28 19:26:09

使用Puppeteer进行数据抓取(三)——简单的示例的相关文章

使用Puppeteer进行数据抓取(二)——Page对象

page对象是puppeteer最常用的对象,它可以认为是chrome的一个tab页,主要的页面操作都是通过它进行的.Google的官方文档详细介绍了page对象的使用,这里我只是简单的小结一下. 客户端模拟 页面模拟设置相关函数有如下几个, page.setViewport: 设置视图大小 page.setUserAget: 设置UserAgent page.SetCookie: 设置Cookie 另外,也可以使用emulate函数提供快捷设置,puppeteer/DeviceDescript

使用Puppeteer进行数据抓取(四)——图片下载

大多数情况下,图片获取并不是很困难的事情,获取图片的url,然后模拟浏览器请求即可.但是,有的时候这种方法往往无法生效,常见的情形有: 动态图片,每次获取都是一个新的,例如图片验证码,重新获取时是一个新的验证码图片,已经失去了效果了. 动态上下文,有的网站为了反爬虫,获取图片时要加上其动态生成的cookie才行. 这些情况下,使用puppeteer驱动chrome浏览器能看到图片,但获取url后单独请求时,要么获取到的图片无效,要么获取不到图片.本文这里就简单的介绍下一些十分通用且有效的下载这些

Twitter数据抓取

说明:这里分三个系列介绍Twitter数据的非API抓取方法,内容主要来自于Tom Dickinson的博客. Tom Dickinson Milton Keynes,I am currently a PhD student at KMI, currently researching extraction of memorable events from social media. My areas of expertise lie in data mining, machine learnin

数据抓取的艺术(三):抓取Google数据之心得

本来是想把这部分内容放到前一篇<数据抓取的艺术(二):数据抓取程序优化>之中.但是随着任务的完成,我越来越感觉到其中深深的趣味,现总结如下: (1)时间     时间是一个与抓取规模相形而生的因素,数据规模越大,时间消耗往往越长.所以程序优化变得相当重要,要知道抓取时间越长,出错的可能性就越大,这还不说程序需要人工干预的情境.一旦运行中需要人工干预,时间越长,干预次数越多,出错的几率就更大了.在数据太多,工期太短的情况下,使用多线程抓取,也是一个好办法,但这会增加程序复杂度,对最终数据准确性产

数据抓取的艺术(三)

原文地址:http://blog.chinaunix.net/uid-22414998-id-3696649.html 本来是想把这部分内容放到前一篇<数据抓取的艺术(二):数据抓取程序优化>之中.但是随着任务的完成,我越来越感觉到其中深深的趣味,现总结如下: (1)时间     时间是一个与抓取规模相形而生的因素,数据规模越大,时间消耗往往越长.所以程序优化变得相当重要,要知道抓取时间越长,出错的可能性就越大,这还不说程序需要人工干预的情境.一旦运行中需要人工干预,时间越长,干预次数越多,出

python-requests 简单实现数据抓取

安装包: requests,lxmlrequest包用于进行数据抓取,lxml用来进行数据解析对于对网页内容的处理,由于html本身并非如数据库一样为结构化的查询所见即所得,所以需要对网页的内容进行分析然后进行内容提取,lxml就是用来完成此项工作在requests中最用的方法为get()方法,通常情况下可以将url做为参数传入进去,对于一些功能比较完善的网站如果存在反爬取数据的功能是则需要设置headers参数内容,内容为一字典类型可以在浏览器中查看User-Agent字段的内容,设置后req

利用Selenium制作python数据抓取,以及对Selenium资源介绍

当当当~第三篇博客开始啦~ 这次的话题是数据抓取.终于到了核心部分的探讨,我的心情也是非常激动啊!如果大家baidu或者google(如果可以的话)数据抓取或者data crawling,将会找到数以千计的例子.但是大多数的代码非常的冗长,并且许多代码还是抓取静态数据之后,对动态JS写成的数据却毫无办法.或者,利用HTML解析网址后,再找到JS写的数据页面来寻找到所想要的数据. 但是!不知各位是否有发现过,如果打开chrome或者safari或者各种浏览器的审查元素.网页上能看到的数据,其实都会

Phantomjs+Nodejs+Mysql数据抓取(1.数据抓取)

概要: 这篇博文主要讲一下如何使用Phantomjs进行数据抓取,这里面抓的网站是太平洋电脑网估价的内容.主要是对电脑笔记本以及他们的属性进行抓取,然后在使用nodejs进行下载图片和插入数据库操作. 先进行所有页面的内容进行抓取 var page =require('webpage').create(); var address='http://product.pconline.com.cn/server/'; var fs = require('fs'); var mypath = 'ver

博客数据抓取总结

今天下午的总结让我发现了自己的几个缺点,立此为证,以求改变. 第一点,事前观察不够仔细.事先在源代码上发现了几个数据就急着着手去做,没有观察完所有的数据,导致做到一半才发现有些是js代码执行后才出现的数据,与一般静态源代码的数据的抓取方式不同. 第二点,坚持耐性尚缺.遇到了因为版本问题等而导不出数据到Excel,动态数据抓取不了,网站各种标记不同等问题,而暂时放弃去做另外的项目.其实这个时候我还有更好的解决方案,就是求助老师.这也就是我的第三点,要记得在关键时候适当得求助别人,不管是老师还是同学