用node+puppeteer騰訊視頻爬取實例

項目簡介

經過騰訊電影的url地址和爬取的頁數來進行頁面數據的爬取。java

項目地址

github地址git

使用庫

  • puppeteer - 抓取數據
  • chalk - 更改console.log
  • file-box - 打包圖片用於wechaty發送
  • fs - 寫入文件

基本思路

  • 抓取騰訊視頻電影的數據
  • 格式化打印的信息
  • 打開要爬取的連接
  • 睡眠幾秒以後再爬取下一頁

安裝模塊

# 安裝puppeteer
npm install puppeteer --save
# puppeteer 須要安裝 chromium,能夠選擇修改 puppeteer 的下載源:
npm config set puppeteer_download_host https://npm.taobao.org/mirrors

# 安裝chalk
npm install chalk --save
複製代碼

最終代碼

const puppeteer = require('puppeteer');
const chalk = require('chalk');
const fs = require('fs');

// 延遲執行
const sleep = time => new Promise(resolve => {
    setTimeout(resolve, time);
});

// console.log 簡寫
const log = console.log;
// 要爬取的網頁數量
const TOTAL_PAGE = 150;

// 爬取的連接
// const url = `https://v.qq.com/x/list/movie?itype=-1&offset=0`;
const url = `https://v.qq.com/channel/movie?listpage=1&channel=movie&itype=100062`;

// 格式化進度輸出
function formatProgress(current) {
    let percent = (current / TOTAL_PAGE) * 100;
    let done = ~~(current / TOTAL_PAGE * 40);
    let left = 40 - done;
    let str = `當前進度:[${''.padStart(done, '=')}${''.padStart(left, '-')}] ${percent}%`;
    return str;
}

(async () => {
    // 啓動瀏覽器環境
    const browser = await puppeteer.launch({
        // headless: false,
        // slowMo: 250
    });
    log(chalk.green('服務正常啓動'))

    try {
        const page = await browser.newPage(); // 打開一個新的頁面
        // 監聽內部的console消息
        page.on('console', message => {
            if (typeof message == 'object') {
                console.dir(message);
            } else {
                log(chalk.blue(message))
            }
        });

        // 打開要爬取的連接
        await page.goto(url, {
            waitUntil: 'networkidle2' // 網絡空閒說明已加載完畢
        });

        log(chalk.yellow('頁面初次加載完畢'));
	await sleep(3000);
        for (let i = 1; i <= TOTAL_PAGE; i++) {
            const submit = await page.$('.page_next'); // 獲取下一頁按鈕
            if (!submit) {
                chalk.red('數據獲取完畢');
                return;
            }
            await submit.click(); // 模擬點擊跳轉下一頁
	    await sleep(3000);
            await page.waitFor(2500); // 等待頁面加載完畢
            console.clear();
            // 打印當前的爬取進度
            log(chalk.yellow(formatProgress(i)));
            log(chalk.yellow('頁面數據加載完畢'));

            await handleData(); // 執行方法
            await sleep(3000);
            await page.waitFor(2500); // 一個頁面爬取完畢之後稍微歇歇
        }

        await browser.close();
        log(chalk.green('服務正常結束'));

        // 獲取瀏覽器內部內容
        async function handleData() {
            const result = await page.evaluate(() => {
                var $ = window.$; // // 拿到頁面上的JQuery
                var itemList = $('.list_item'); // 拿到全部的item
                var links = []; // 存儲爬取的數據
                // 循環寫進數組
                itemList.each((index, item) => {
                    let i = $(item);
                    let vid = i.find('.figure').data('float'); // id
                    let link = i.find('.figure').attr('href'); // 連接地址
                    let star = i.find('.figure_desc').attr('title'); // 主演
                    let title = i.find('.figure_pic').attr('alt'); // 電影名稱
                    let poster = i.find('.figure_pic').attr('src'); // 封面圖片
                    let count = i.find('.figure_count').text(); // 播放量
                    // 存進以前定義好的數組中
                    links.push({
                        vid,
                        title,
                        count,
                        star,
                        poster,
                        link
                    });
                });
                return links; // 返回數據
            });

            // 寫入json文件中
            fs.writeFile('./movie.json', JSON.stringify(result, null, '\t', {
                'flag': 'a'
            }), function (err) {
                if (err) {
                    throw err;
                }
            });
            log(chalk.yellow('寫入數據完畢'));
        }
    } catch (error) {
        console.log(error)
        log(chalk.red('服務意外終止'))
        await browser.close()
    } finally {
        process.exit(0);
    }
})();
複製代碼

第一次寫,寫的很差請你們見諒,後續會繼續努力的。github

相關文章
相關標籤/搜索