Node.js抓取汽车数据入库Mongodb

388 阅读1分钟

从零开始Node.js抓取汽车数据入库Mongodb

接口地址可以从通过谷歌浏览控制台看到和分析出来

截屏2021-10-20 下午11.53.02.png

截屏2021-10-21 上午9.07.12.png

  1. 初始化我们的项目
// qichezhijia 在当前文件夹下面运行
npm init
// 初始化成功,会生成packge.json

// 添加所需要包
npm install mongodb
npm install axios

// 解决GBK页面中文乱码原因
// 编写 Node.js Http 请求时候,发现请求GBK页面,会造成中文乱码
npm install iconv-lite

  1. 找寻接口数据,对着谷歌浏览器看控制台请求
// 下载地址 https://www.autohome.com.cn/js/index/findcarnew_branddata.js
// 引入进去
const IndexFindCarBrand = require('./findcarnew_branddata').IndexFindCarBrand;

  1. 开始连接MongoDb
const { MongoClient } = require('mongodb');
var url = "mongodb://localhost:27017";
const client = new MongoClient(url);
const dbName = 'qichezhijia';
async function main() {
    await client.connect();
    // 如果数据库存在切换 不存在创建
    const db = client.db(dbName);
    console.log(`create connect success! dbName:${dbName}`);
  	// 数据库链接成功之后操作
    return 'done.';
}

main()
    .then(console.log)
    .catch(console.error)
    .finally(() => client.close());

  1. 处理HTTP编码GBK请求中文乱码
const iconv = require('iconv-lite');
var qicheConfig = {
    responseType: "arraybuffer",
    transformResponse: [function (data) {
        return iconv.decode(data, 'gbk');
    }],
}
  1. 入库方法接口方法封装 使用Promise处理异步问题
// 根据车型品牌ID发送Http请求
async function GetHomeFindCar(id, letter, dbo) {
    return new Promise((resolve, reject) => {
        axios.get(`https://www.autohome.com.cn/ashx/index/GetHomeFindCar.ashx?type=1&brandid=${id}&v=1`, qicheConfig).then((response) => {
            var result = JSON.parse(response.data).result;
            // // 把首字母放到文档上去
            result.letter = letter;
            console.log(result);
            dbo.collection('car_info').insertOne(result).then(() => {
                resolve();
            })

        });
    });
}


// 根据车系ID查询所有
async function GetHomeFindCarModel(id, dbo) {
    return new Promise((resolve, reject) => {
        var url = `https://www.autohome.com.cn/ashx/index/GetHomeFindCar.ashx?type=2&seriesid=${id}&format=json&v=1`;
        axios.get(url, qicheConfig).then((response) => {
            if (response.data == '') {
                resolve();
            } else {
                var result = JSON.parse(response.data);
                for (var item of result) {
                    var list = item.list.map(c => {
                        c.seriesid = id;
                        c.type = item.name
                        return c;
                    });

                    var taskStack = [];
                    for (var carModel of list) {
                        taskStack.push(new Promise((resolve, reject) => {
                            dbo.collection("car_model").insertOne(carModel, function (err, res) {
                                if (err) throw err;
                                resolve();
                            });

                        }));
                    }
                }
                Promise.all(taskStack).then(() => {
                    console.log(`${id} 文档插入成功`);
                    resolve();
                });
            }
        });
    })
}
  1. 根据品牌请求车系详细信息并且入库(Mongodb)
// IndexFindCarBrand 是第一个引入的品牌数据 (格式如下)
// [ { id: 33, name: '奥迪', letter: 'A' }] 
// 数据库链接成功之后操作
var taskStack = [];
for (var item of IndexFindCarBrand) {
    taskStack.push(GetHomeFindCar(item.id, item.letter, db));
}
await Promise.all(taskStack);
// 等待所有 taskStack 请求全部结束

console.log("请求成功");
var serieslist = await db.collection('car_info').aggregate([{ $unwind: "$fctlist" }, { $unwind: "$fctlist.serieslist" }]).toArray();
var seriesids = serieslist.map(c => c.fctlist.serieslist.seriesid);
var carModelTask = [];
for (var item of seriesids) {
    carModelTask.push(GetHomeFindCarModel(item, db));
}
await Promise.all(carModelTask);
console.log("所有文档插入成功");

完结 !!