Node JS爬蟲:爬取瀑布流網(wǎng)頁高清圖

原文鏈接:[Node JS爬蟲:爬取瀑布流網(wǎng)頁高清圖]https://www.bougieblog.cn/blog/2018/05/16%20-%20Node%20JS%E7%88%AC%E8%99%AB%EF%BC%9A%E7%88%AC%E5%8F%96%E7%80%91%E5%B8%83%E6%B5%81%E7%BD%91%E9%A1%B5%E9%AB%98%E6%B8%85%E5%9B%BE.html)

靜態(tài)為主的網(wǎng)頁往往用get方法就能獲取頁面所有內(nèi)容。動(dòng)態(tài)網(wǎng)頁即異步請(qǐng)求數(shù)據(jù)的網(wǎng)頁則需要用瀏覽器加載完成后再進(jìn)行抓取。本文介紹了如何連續(xù)爬取瀑布流網(wǎng)頁。

在知乎提到python就必有一大幫人提起爬蟲,咱Node JS爬蟲也是非常簡(jiǎn)單的,和python相比僅僅是“異步”和“多線程”的性能對(duì)比而已。對(duì)python了解不多,故對(duì)此不做評(píng)價(jià)。

phantomjs是一個(gè)‘無殼’的chrome,具體安裝方法查看phantomjs.org。phantomjs提供命令行工具運(yùn)行,運(yùn)行需使用命令phantom xxx.js。使用phantom-node這個(gè)庫(kù)可以在Node Js中把玩phantomjs,這樣就可以使用pm2進(jìn)行進(jìn)程守護(hù)和負(fù)載均衡了。

目標(biāo)

爬取200張以上的1920*1080分辨率的動(dòng)漫壁紙,網(wǎng)頁是百度瀑布流圖片

image

方式

瀑布流是根據(jù)頁面滾動(dòng)位置來判斷是否繼續(xù)往下加載,故要利用phantomjs滾動(dòng)頁面來獲取更多圖片鏈接。單個(gè)圖片詳細(xì)頁面剛進(jìn)入時(shí)是壓縮過的圖片,這是百度優(yōu)化訪問速度的措施,等待幾秒圖片src就會(huì)替換成大圖的鏈接。因此,進(jìn)入圖片詳細(xì)頁時(shí)應(yīng)延遲幾秒再獲取圖片src,具體延遲幾秒視你網(wǎng)速而定。

步驟

獲取鏈接

首先利用phantom打開網(wǎng)頁

const phantom = require('phantom')

(async function() {
    const instance = await phantom.create();
    const page = await instance.createPage();
    const status = await page.open(url);
    const size = await page.property('viewportSize', {
        width: 1920,
        height: 1080
    })
}())

獲取鏈接數(shù)量,不足200則滾動(dòng)網(wǎng)頁

// 添加一個(gè)延時(shí)函數(shù),等待頁面加載后再滾動(dòng)
function delay(second) {
    return new Promise((resolve) => {
        setTimeout(resolve, second * 1000);
    });
}
async function pageScroll(i) {
    await delay(5)
    await page.property('scrollPosition', {
        left: 0,
        top: 1000 * i
    })
    let content = await page.property('content')
    let $ = cheerio.load(content)
    console.log($('.imgbox').length)
    if($('.imgbox').length < 200) {
        await pageScroll(++i)
    }
}
await pageScroll(0)

提取圖片鏈接

let urlList = []
$('.imgbox').each(function() {
    urlList.push('https://image.baidu.com'+$(this).find('a').attr('href'))
})

保存圖片

定義保存圖片的函數(shù)

const request = require('request')
const fs = require('fs')

function save(url) {
    let ext = url.split('.').pop()
    request(url).pipe(fs.createWriteStream(`./image/${new Date().getTime()}.${ext}`));
}

遍歷urlList,建議用遞歸遍歷,循環(huán)遍歷delay不起作用

async function imgSave(i) {
    let page = await page.open(urlList[i])
    delay(1)
    let content = await page.property('content')
    $ = cheerio.load(content)
    let src = $('#currentImg').attr('src')
    save(src)
    if(i<urlList.length) {
        await imgSave(++i)
    }
}
await imgSave(0)

最后爬取結(jié)果如圖,都是高分辨率的,部分圖片做了防爬處理


image

完整代碼

const phantom = require('phantom')
const cheerio = require('cheerio')
const request = require('request')
const fs = require('fs')
function delay(second) {
    return new Promise((resolve) => {
        setTimeout(resolve, second * 1000);
    });
}
let url = 'https://image.baidu.com/search/index?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=-1&st=-1&fm=index&fr=&hs=0&xthttps=111111&sf=1&fmq=&pv=&ic=0&nc=1&z=&se=1&showtab=0&fb=0&width=&height=&face=0&istype=2&ie=utf-8&word=%E5%8A%A8%E6%BC%AB+%E5%A3%81%E7%BA%B8&oq=%E5%8A%A8%E6%BC%AB+%E5%A3%81%E7%BA%B8&rsp=-1'
function save(url) {
    let ext = url.split('.').pop()
    request(url).pipe(fs.createWriteStream(`./image/${new Date().getTime()}.${ext}`));
}
(async function() {
    let instance = await phantom.create();
    let page = await instance.createPage();
    let status = await page.open(url);
    let size = await page.property('viewportSize', {
        width: 1920,
        height: 1080
    })
    let $
    async function pageScroll(i) {
        await delay(1)
        await page.property('scrollPosition', {
            left: 0,
            top: 1000 * i
        })
        let content = await page.property('content')
        $ = cheerio.load(content)
        if($('.imgbox').length < 200) {
            await pageScroll(++i)
        }
    }
    await pageScroll(0)
    let urlList = []
    $('.imgbox').each(function() {
        urlList.push('https://image.baidu.com'+$(this).find('a').attr('href'))
    })
    async function imgSave(i) {
        let status = await page.open(urlList[i])
        await delay(1)
        let content = await page.property('content')
        $ = cheerio.load(content)
        let src = $('#currentImg').attr('src')
        save(src)
        if(i<urlList.length) {
            await imgSave(++i)
        }
    }
    await imgSave(0)
    await instance.exit()
}());

我的博客:www.bougieblog.cn,歡迎前來尬聊。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 你可能會(huì)把 NodeJS 用作網(wǎng)絡(luò)服務(wù)器,但你知道它還可以用來做爬蟲嗎? 本教程中會(huì)介紹如何爬取靜態(tài)網(wǎng)頁——還有那...
    張嘉夫閱讀 5,200評(píng)論 3 51
  • 爬蟲文章 in 簡(jiǎn)書程序員專題: like:128-Python 爬取落網(wǎng)音樂 like:127-【圖文詳解】py...
    喜歡吃栗子閱讀 22,677評(píng)論 4 411
  • 爬蟲文章 in 簡(jiǎn)書程序員專題: like:128 - Python 爬取落網(wǎng)音樂 like:127 - 【圖文詳...
    treelake閱讀 29,741評(píng)論 33 638
  • ** 有些時(shí)候項(xiàng)目已經(jīng)竣工或者已經(jīng)迭代好幾個(gè)版本了,如果這個(gè)時(shí)候要實(shí)現(xiàn)本地化,那該如何處理呢。** 篩選項(xiàng)目中的中...
    wutongyu閱讀 432評(píng)論 0 1
  • 看車窗極速后退 課本合上又翻開 蒲公英聚攏手中 雨點(diǎn)回到半空 你收起打開的傘 笑著說 嘿,我記得你
    木木和桓桓閱讀 235評(píng)論 0 5

友情鏈接更多精彩內(nèi)容