Node爬虫類が豆弁を這い出す映画データ

29403 ワード

概要
SuperAgentは、NodeJS環境で使用される軽量レベル、柔軟、読みやすい、低学習曲線のクライアントリクエストエージェントモジュールです.cheerioはjqueryコア機能の高速で柔軟で簡潔な実現であり、主にサーバ側でDOMを操作する必要がある場所でPuppeteerを使用するためにNodeライブラリであり、DevToolsプロトコルによってChromiumまたはChromeをデフォルトでheadlessモードで実行するための高度なAPIを提供している.ただし、プロファイルを変更してヘッダモードを実行できます.
ドキュメント
superagentドキュメントpuppeteerドキュメント
インストール
npm install superagent cheerio puppeteer
superagentはサービス側でレンダリングされたデータしか取得できません.jsによって非同期にロードされたデータは取得できません.
コード#コード#
豆弁の映画データ部分はajax非同期ロードがあるため、直接superagentを使用して這い出すことはできません.puppeteerで協力するには、superagentを使用してリンク(速度が速い)を取得し、puppeteerを使用してリンクに基づいて映画の詳細データを這い出す必要があります.
完全なコード
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;
}