爬虫与NodeJs(一)

特别申明:阅读本文以后,请勿滥用爬虫采集资源,攻击他人服务器。javascript

网络爬虫(又称为网页蜘蛛,网络机器人,在FOAF社区中间,更常常的称为网页追逐者),是一种按照必定的规则,自动地抓取万维网信息的程序或者脚本。另一些不常使用的名字还有蚂蚁、自动索引、模拟程序或者蠕虫html

开门见山,小编所接触到的爬虫分为两种,一种为基本的http或https请求,使用网络请求来获取目标内容。第二种为无头浏览器,能够将目标页面直接运行在无头浏览器中。两种方法各有利弊,接下来咱们详细了解一下。前端

小编是一名前端程序员,熟悉javascript,因此这里的举例都是使用nodejs代码。先来讲说第一种爬虫,使用http请求的方式。java

http请求

咱们可使用nodejs种的http(s)模块来请求目标网址,也可使用axios这样的第三方库来请求网页。拿到html后使用html解析库将其解析为方便操做的js对象,而后抓去目标内容。解析库这里推荐使用cheerio。cheerio提供了相似jQuery的操做方法,能够轻松的抓去到咱们想要的内容。node

// demo1
const cheerio = require('cheerio')
const axios = require('axios')

async function main() {
    const resp = await axios.get('https://www.jianshu.com/')
    console.log(resp.data)
}

main()
复制代码

经过node demo1执行demo1,咱们能够拿到简书首页的html。 ios

image.png

咱们如今来完善demo1的代码,将html使用cheerio解析。程序员

// demo1
const cheerio = require('cheerio')
const axios = require('axios')

async function main() {
    const resp = await axios.get('https://www.jianshu.com/')
    const $ = cheerio.load(resp.data)
    const articleList = []
    $('#list-container li').each((i, el) => {
        articleList.push({
            id: $(el).attr('id').replace('note-', ''),
            title: unescape($(el).find('.title').html().replace(/&#x/g, '%u').replace(/;/g, '')),
            href: $(el).find('.title').attr('href'),
        })
    })
    console.log(articleList)
}

main()
复制代码

image.png

这样咱们就拿到了文章的id,标题和连接了。axios

这种方式抓取数据的优势是效率高,占用的硬件资源也不多。可是这种方法也存在一些劣势。例如懒加载页面就很难爬取。由于懒加载的页面的内容是由浏览器js动态加载的,这样一来,咱们所请求到的页面,因为js尚未将内容渲染到页面上,咱们就没法正确拿到页面内容,而且咱们的请求也没法提供页面js所需的运行环境。这时候就要引出咱们的另外一种爬虫了。浏览器

无头浏览器

无头浏览器是指没有操做界面的,在后台运行的网络浏览器程序。经常使用的无头浏览器有PhantomJS,Selenium,Puppeteer等(还有不少不少哦,有兴趣能够本身查阅)。bash

无头浏览器常被用于自动化测试、爬虫等技术。它提供了浏览器js所需的运行环境,咱们能够利用这一点,来对付懒加载的页面。

Puppeteer是谷歌发布的一款Chromium无头浏览器。在这里咱们以Puppeteer为例,来写一些小demo。

// demo2
const puppeteer = require('puppeteer');

async function main() {
    const browser = await puppeteer.launch({
        // 是否为无头,无头模式下没有用户操做界面
        headless: false,
        defaultViewport: null
    })
    const page = await browser.newPage();
    await page.goto('https://www.jianshu.com/u/04d11dd2f924');
}

main()
复制代码

咱们来使用node demo2来执行:

image.png

咱们如今已经使用代码打开了一个浏览器窗口。接下来,咱们将继续完善demo2来抓取此页面的内容。

// demo2
const puppeteer = require('puppeteer');

async function main() {
    const browser = await puppeteer.launch({
        // 是否为无头,无头模式下没有用户操做界面
        headless: false,
        defaultViewport: null,
        devtools: true,
    })
    const page = await browser.newPage();
    await page.goto('https://www.jianshu.com/u/04d11dd2f924');
    const articleList = await page.$$eval('#list-container li', els =>
        els.map(el => {
            const id = el.dataset.noteId
            const title = el.querySelector('.title').innerText
            const url = el.querySelector('.title').href
            return {id, title, url}
        })
    )
    console.log(articleList)
}

main()
复制代码

执行该代码,咱们获得以下结果:

image.png

这就是无头浏览器的基本使用。它还提供了不少方便操做的API,例如page.waitFor(selector, pageFun)方法,能够等待某个元素出如今页面后再去执行pageFun方法.还有page.addScriptTag(options)方法,能够直接在页面注入你本身的js脚本。

在这里,再次申明,请勿滥用爬虫采集资源,攻击他人服务器。

两种方式的对比

http 方式: 优势:占用的硬件资源少,响应速度更快; 缺点:没法抓取懒加载页面,没法获取更多信息,例如cookie,localStorage等。

无头浏览器 方式: 优势:提供完整浏览器运行环境,能够抓取懒加载页面的内容,也能够获取页面cookie等本地存储,能够在页面注入js代码,能够模拟键盘输入,鼠标点击等操做; 缺点:占用的硬件资源高,会去执行页面代码,在关闭无头模式的状况下还要去渲染页面,响应速度慢。

详细对比了两种方式之后,咱们发现两种方式各有利弊。其实,在实际使用中,咱们能够混搭使用,既保证了执行效率,一样也能保证信息的完整性。

今天就介绍道这里了,喜欢的简友能够点赞并关注,随后我就继续更新几篇爬虫相关的文章。

本文版权全部,禁止转载!

相关文章
相关标签/搜索