node crawler简单使用

需求:获取某一个网站,商品的名称+价格;

以下按京东商品列表URL进行测试,

1、搭建node环境,此node安装不多介绍

2、node爬虫工具,安装 npm install crawler

3、创建index.js,直接贴代码

/**
 * 此js主要是通过PATH_URL,根据源码中的html风格,根据特定的标签获取HTML中的href,写入JSON文件中
 */
const fs = require('fs');
const Crawler = require('crawler');
const _ = require('lodash')

//在爬相关图片信息时,需要得到指定的URL:https://search.jd.com, 
const PATH_URL = 'https://search.jd.com/Search?keyword=%E5%8D%8E%E4%B8%BA%E6%89%8B%E6%9C%BA&enc=utf-8&suggest=5.def.0.base&wq=huawie%E6%89%8B%E6%9C%BA&pvid=b314d64bbf02446187feba4eed246377';

// 为了console输出而定义的变量
let cnt = 0;
// 查找到的HTML地址
let listDataRes = []

// 爬虫抓取
const c = new Crawler({
  maxConnections: 10,
  retries: 3,  // 失败重连3次
  callback: function (error, res, done) {
    if (error) {
      console.log(error)
    } else {
      // 注:抓取图片的规则,需要自己定义
      const $ = res.$;
      console.log(' ------------>title: ', $('title').text())
      const dataList = $('.goods-list-v2 li');

      dataList.each((index, dataItem) => {
        let dataRes = {};
        const idKey = dataItem.attribs['data-sku']

        // 获取li标签下的标签集合
        const firstChildren = dataItem.children
        firstChildren.forEach(twoItem => {
          // 得到相关div标签
          if (twoItem.type === 'tag' && twoItem.name === 'div') {
            const twoChildren = twoItem.children

            twoChildren.forEach(threeItem => {
              // -------> 获取商品价格
              if (threeItem.type === 'tag' && threeItem.name === 'div' && threeItem.attribs.class === 'p-price') {
                const threeChildren = threeItem.children
                // 获取strong标签
                threeChildren.forEach(fourItem1 => {
                  if (fourItem1.type === 'tag' && fourItem1.name === 'strong') {
                    const fourItem1Children = fourItem1.children
                    // 获取i标签
                    fourItem1Children.forEach(fiveItem1 => {
                      if (fiveItem1.type === 'tag' && fiveItem1.name === 'i') {
                        const price = (fiveItem1.children[0]).data
                        dataRes.price = price
                      }
                    })
                  }
                })
              }

              // -------> 获取商品名称
              if (threeItem.type === 'tag' && threeItem.name === 'div' && threeItem.attribs.class === 'p-name p-name-type-2') {
                const threeChildren2 = threeItem.children
                // 获取strong标签
                threeChildren2.forEach(fourItem2 => {
                  if (fourItem2.type === 'tag' && fourItem2.name === 'a') {
                    const fourItem2Children = fourItem2.children
                    // 获取i标签
                    fourItem2Children.forEach(fiveItem3 => {
                      if (fiveItem3.type === 'tag' && fiveItem3.name === 'em') {
                        const fiveItem3Children = fiveItem3.children
                        const fiveItem3ChildrenObj = fiveItem3Children.find(f => f.type === 'text')
                        const name = fiveItem3ChildrenObj ? fiveItem3ChildrenObj.data : ''
                        dataRes.name = name
                      }
                    })
                  }
                })
              }
            })
          }
        })

        if (!_.isEmpty(dataRes)) {
          listDataRes.push(dataRes);
        }
      })

      console.log(`${cnt++}`); //这里就是为了自己在console中看到进度,没有实际用处。
    }
    done(); // 函数在回调中完成工作后必须调用它
  }
});

// 将其相关href写入json文件
const writeListJson = () => {
  console.log(' =================> 队列为空时,数据处理完成')
  // 写入文件内容(如果文件不存在会创建一个文件)
  fs.writeFile('./jd_data/jd_goods_list.json', JSON.stringify(listDataRes), function (err) {
    if (err) {
      throw err;
    }
    console.log('all requests done and json saved!');
  });
}

// 指定爬取一个Url,将其添加到队列中
//绝大多数网站,都有反爬机制。只有小众网站没有。所以我们需要使用以下配置
//浏览器可以下载,但是服务端爬虫无效。反爬:检测你这个请求是通过浏览器发出来,还是服务端(解决方案:让服务端伪装成浏览器来发这个请求)
c.queue({
  url: PATH_URL,
  headers: { 'User-Agent': 'requests' }//让服务端伪装成客户端
});

// 在队列为空时,调用以下函数
c.on('drain', writeListJson);

4、cmd进入到index.js目录,执行 node index.js,生成如下

注意:简单的页面抓取数据,很容易实现。效果也不错,主要是根据HTML标签规则自定义获取数据。

目前存在一个问题:

例如:打开京东商品URL时,源码中展示的为30个商品信息列表,在鼠标向下滑动时,会自动追加商品数量,滑动到底部时查看源码中商品数量已增加到60个。

(刚开始研究node抓取数据)问题为在以上例子中只能抓取首屏的数据,那么如何滑动滚轮动态加载内容爬取?哪位大哥知道的,劳驾留个言指教一下小弟,先在此谢谢了。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值