數據采集實戰(五)-- 當當網童書排名


1. 概述

現在學校越來越重視孩子課外知識的掌握,給孩子挑選課外書一般都是參考學校或者家長之間的推薦。
有時,也會想看看在兒童階段,目前到底流行的是些什么樣的書。

於是,就簡單寫了這個小爬蟲,采集了暢銷童書的前20名。
要想采集更多的暢銷童書,后者采集其他類型的暢銷書,調整相應的參數和URL就可以了。

2. 采集流程

因為當當網的圖書排名不需要登錄就可以查看,而且采集前20名也不需要翻頁,所以流程很簡單,打開網頁直接解析保存就可以了。

核心代碼如下:

import { saveContent } from "../utils.js";

const http_prefix = "http://bang.dangdang.com/books/childrensbooks";

const age_start = 1;
const age_end = 4;
const month_start = 1;
const month_end = 11; // 目前只到11月

const age_map = { 1: "0~2歲", 2: "3~6歲", 3: "7~10歲", 4: "11~14歲" };

const childrensbooks = async (page) => {
    // 0~2歲, 3~6歲,7~10歲,11~14歲
    for (let i = age_start; i <= age_end; i++) {
        for (let m = month_start; m <= month_end; m++) {
            let url = `${http_prefix}/01.41.0${i}.00.00.00-month-2021-${m}-1-1-bestsell`;
            const lines = await parseData(page, url);

            // 分年齡段分月份寫入csv
            await saveContent(
                `./output/dangdang-childrenbook`,
                `2021-${m}-${age_map[i]}.csv`,
                lines.join("\n")
            );
        }
    }
};

// 采集字段: 排名order,書名name,評論數comment,推薦率recommend_pct,作者author,出版日期publish_date,出版社publisher
const parseData = async (page, url) => {
    await page.goto(url);

    const listContent = await page.$$("ul.bang_list>li");
    let lines = [
        "排名order,書名name,評論數comment,推薦率recommend_pct,作者author,出版日期publish_date,出版社publisher",
    ];
    for (let i = 0; i < listContent.length; i++) {
        const order = await listContent[i].$eval(
            "div.list_num",
            (node) => node.innerText
        );

        const name = await listContent[i].$eval(
            "div.name>a",
            (node) => node.innerText
        );
        const comment = await listContent[i].$eval(
            "div.star>a",
            (node) => node.innerText
        );
        const recommend_pct = await listContent[i].$eval(
            "div.star>span.tuijian",
            (node) => node.innerText
        );
        const publisher_info = await listContent[i].$$("div.publisher_info");
        const authors = await publisher_info[0].$$eval("a", (nodes) =>
            nodes.map((node) => node.innerText)
        );

        const author = authors.join("&");
        const publish_date = await publisher_info[1].$eval(
            "span",
            (node) => node.innerText
        );
        const publisher = await publisher_info[1].$eval(
            "a",
            (node) => node.innerText
        );

        const line = `${order},${name},${comment},${recommend_pct},${author},${publish_date},${publisher}`;
        lines.push(line);
        console.log(line);
    }

    return lines;
};

export default childrensbooks;

采集之后的內容分門別類的按照月份和年齡階段保存的。
image.png

文件的內容是csv格式的(下圖是其中部分字段)。
image.png

3. 總結

以上內容是通過 puppeteer 采集的,除了童書排行榜,還有圖書暢銷榜,新書熱賣榜,圖書飆升榜,特價榜,五星圖書榜等等。
各個榜單的結構都類似,只需要修改上面代碼中的 http_prefix,以及童書年齡階段的循環控制等,就能采集相應數據。

4. 注意事項

爬取數據只是為了研究學習使用,本文中的代碼遵守:

  1. 如果網站有 robots.txt,遵循其中的約定
  2. 爬取速度模擬正常訪問的速率,不增加服務器的負擔
  3. 只獲取完全公開的數據,有可能涉及隱私的數據絕對不碰


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM