node爬蟲爬取豆瓣電影數據

簡介

SuperAgent是一個輕量級、靈活的、易讀的、低學習曲線的客戶端請求代理模塊,使用在NodeJS環境中。
cheerio是jquery核心功能的一個快速靈活而又簡潔的實現,主要是爲了用在服務器端需要對DOM進行操作的地方
Puppeteer 是一個 Node 庫,它提供了一個高級 API 來通過 DevTools 協議控制 Chromium 或 Chrome 默認以 headless 模式運行,但是可以通過修改配置文件運行“有頭”模式。

文檔

superagent文檔:http://visionmedia.github.io/superagent
puppeteer文檔:https://zhaoqize.github.io/puppeteer-api-zh_CN/

安裝

npm install superagent
npm install cheerio
npm install puppeteer

完整代碼

由於豆瓣的電影數據部分是有ajax異步加載的,不能使用superagent來爬取,要配合puppeteer爬取,拷貝下面代碼,要保證在node環境中並安裝了superagent,cheerio,puppeteer,然後直接node 運行

const superagent = require('superagent');
const cheerio = require('cheerio');
const puppeteer = require('puppeteer');
const fs = require('fs');

let movieURL = [] //存放鏈接
var movieIdex = 0  //計數
let index=3 //點擊次數

getFile('img')
puppData()

// 先使用puppeteer爬取鏈接
async function puppData() {
    const browser = await puppeteer.launch({ headless: false, ignoreDefaultArgs: ["--enable-automation"] });
    const page = await browser.newPage();
    await page.goto(`https://movie.douban.com/tag/#/?sort=U&range=0,10&tags=&start=0`);
    await page.setDefaultNavigationTimeout(600000);
    await page.waitFor('.more');
    let timer = setInterval(async function () {//3秒點一次加載更多
        await page.click('.more');
        movieIdex++
        if (movieIdex >= index) {
            clearInterval(timer)
            let a = await page.$$eval('.list-wp>.item', e => {
                let arr = []
                for (var i = 0; i < e.length; i++) {
                    arr.push(e[i].href)
                }
                return arr
            })
            await browser.close(); //爬取鏈接完成,關閉無頭瀏覽器
            movieURL.push(...a)
            fs.writeFile('b.json', JSON.stringify(movieURL), { flag: 'a', encoding: 'utf-8', mode: '0666' }, function (err) { //保存在b.json
                if (err) throw err;
                fs.readFile('b.json', 'utf8', (err, doc) => {//由於怕中途出錯誤,所以先把鏈接保存到b.json,再讀取b.json
                    if (err) throw err;
                    let bItem = JSON.parse(doc)
                    bItem.map((item) => {
                        getVideo(item)
                    })
                })
            })
        }
    }, 3000)
}

// 用superagent爬取電影數據
async function getVideo(url) {
    let html = await superagent.get(url);
    let $ = cheerio.load(html.text);
    let protagonist = ''
    $('#info>span').eq('2').find('a').text(function (index, item) {
        return protagonist += item + '|'
    })
   var info = {
        url: getImg($('#mainpic img').attr('src')),  //圖片
        name: $('h1').find('span').text(),  //片名
        year: $('h1 .year').text(),  //時間
        grade: $('.rating_num').text(), //評分
        rating_people: $('.rating_people span').text(), //影評數
        director: $('#info>span').eq('0').find('a').text(), //導演
        scriptwriter: $('#info>span').eq('1').find('a').text(), //編劇
        protagonist, //主演
        type: $('#info>span').eq('5').text() + '|' + $('#info>span').eq('6').text(), //類型
        releaseDate: $('#info>span').eq('-5').text(),//上映日期
        min: $('#info>span').eq('-3').text(),//片長
        brief:$('#link-report span').text()//簡介
    }
    fs.writeFile('a.json', JSON.stringify(info)+',', { flag: 'a', encoding: 'utf-8', mode: '0666' }, function (err) {
        if (err) throw err;
    })
}

//爬取圖片
function getImg(imgUrl) {
    let name = randomString(32) + '.jpg'
    superagent
        .get(imgUrl)
        .end(function (err, sres) {
            if (err) throw err;
            fs.writeFile("./img/" + name, sres.body, "binary", function (err) {
                if (err) throw err;
            })
        })
    return name
}


//創建img文件
function getFile(file) {
    if (!fs.existsSync(file)) {
        fs.mkdirSync(file);
    }
}

//對圖片重命名
function randomString(len) {
    len = len || 32;
    var $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';
    var maxPos = $chars.length;
    var pwd = '';
    for (let i = 0; i < len; i++) {
        pwd += $chars.charAt(Math.floor(Math.random() * maxPos));
    }
    return pwd;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章