手把手教你写带登录的NodeJS爬虫+数据展示

其实在早之前,就做过立马理财的销售额统计,只不过是用前端js写的,需要在首页的console调试面板里粘贴一段代码执行,点击这里。主要是通过定时爬取https://www.lmlc.com/s/web/home/user_buying异步接口来获取数据。然后通过一定的排重算法来获取最终的数据。但是这样做有以下缺点:
1. 代码只能在浏览器窗口下运行,关闭浏览器或者电脑就失效了
2. 只能爬取一个页面的数据,不能整合其他页面的数据
3. 爬取的数据无法存储到本地
4. 上面的异步接口数据会部分过滤,导致我们的排重算法失效

由于最近学习了node爬虫相关知识,我们可以在后台自己模拟请求,爬取页面数据。并且我开通了阿里云服务器,可以把代码放到云端跑。这样,1、2、3都可以解决。4是因为之前不知道这个ajax接口是每三分钟更新一次,这样我们可以根据这个来排重,确保数据不会重复。说到爬虫,大家想到的比较多的还是python,确实python有Scrapy等成熟的框架,可以实现很强大的爬取功能。但是node也有自身的优点,凭借强大的异步特性,可以很轻松的实现高效的异步并发请求,节省cpu的开销。其实node爬虫还是比较简单的,下面我们就来分析整个爬虫爬取的流程和最终如何展示数据的。

线上地址

一、爬虫流程

我们最终的目标是实现爬取立马理财每日的销售额,并知道卖了哪些产品,每个产品又被哪些用户在什么时间点买的。首先,介绍下爬虫爬取的主要步骤:

1. 结构分析

我们要爬取页面的数据,第一步当然是要先分析清楚页面结构,要爬哪些页面,页面的结构是怎样的,需不需要登录;有没有ajax接口,返回什么样的数据等。

2. 数据抓取

分析清楚要爬取哪些页面和ajax,就要去抓取数据了。如今的网页的数据,大体分为同步页面和ajax接口。同步页面数据的抓取就需要我们先分析网页的结构,python抓取数据一般是通过正则表达式匹配来获取需要的数据;node有一个cheerio的工具,可以将获取的页面内容转换成jquery对象,然后就可以用jquery强大的dom API来获取节点相关数据, 其实大家看源码,这些API本质也就是正则匹配。ajax接口数据一般都是json格式的,处理起来还是比较简单的。

3. 数据存储

抓取的数据后,会做简单的筛选,然后将需要的数据先保存起来,以便后续的分析处理。当然我们可以用MySQL和Mongodb等数据库存储数据。这里,我们为了方便,直接采用文件存储。

4. 数据分析

因为我们最终是要展示数据的,所以我们要将原始的数据按照一定维度去处理分析,然后返回给客户端。这个过程可以在存储的时候去处理,也可以在展示的时候,前端发送请求,后台取出存储的数据再处理。这个看我们要怎么展示数据了。

5. 结果展示

做了这么多工作,一点展示输出都没有,怎么甘心呢?这又回到了我们的老本行,前端展示页面大家应该都很熟悉了。将数据展示出来才更直观,方便我们分析统计。

二、爬虫常用库介绍

1. Superagent

Superagent是个轻量的的http方面的库,是nodejs里一个非常方便的客户端请求代理模块,当我们需要进行get、post、head等网络请求时,尝试下它吧。

2. Cheerio

Cheerio大家可以理解成一个 Node.js 版的 jquery,用来从网页中以 css selector 取数据,使用方式跟 jquery 一模一样。

3. Async

Async是一个流程控制工具包,提供了直接而强大的异步功能mapLimit(arr, limit, iterator, callback),我们主要用到这个方法,大家可以去看看官网的API。

4. arr-del

arr-del是我自己写的一个删除数组元素方法的工具。可以通过传入待删除数组元素index组成的数组进行一次性删除。

5. arr-sort

arr-sort是我自己写的一个数组排序方法的工具。可以根据一个或者多个属性进行排序,支持嵌套的属性。而且可以再每个条件中指定排序的方向,并支持传入比较函数。

三、页面结构分析

先屡一下我们爬取的思路。立马理财线上的产品主要是定期和立马金库(最新上线的光大银行理财产品因为手续比较麻烦,而且起投金额高,基本没人买,这里不统计)。定期我们可以爬取理财页的ajax接口:https://www.lmlc.com/web/product/product_list?pageSize=10&pageNo=1&type=0。(update: 定期近期没货,可能看不到数据,可以看1月19号以前的)数据如下图所示:

理财页ajax接口数据

这里包含了所有线上正在销售的定期产品,ajax数据只有产品本身相关的信息,比如产品id、筹集金额、当前销售额、年化收益率、投资天数等,并没有产品被哪些用户购买的信息。所以我们需要带着id参数去它的产品详情页爬取,比如立马聚财-12月期HLB01239511。详情页有一栏投资记录,里边包含了我们需要的信息,如下图所示:

详情页投资记录

但是,详情页需要我们在登录的状态下才可以查看,这就需要我们带着cookie去访问,而且cookie是有有效期限制的,如何保持我们cookie一直在登录态呢?请看后文。

其实立马金库也有类似的ajax接口:https://www.lmlc.com/web/product/product_list?pageSize=10&pageNo=1&type=1,但是里边的相关数据都是写死的,没有意义。而且金库的详情页也没有投资记录信息。这就需要我们爬取一开始说的首页的ajax接口:https://www.lmlc.com/s/web/home/user_buying。但是后来才发现这个接口是三分钟更新一次,就是说后台每隔三分钟向服务器请求一次数据。而一次是10条数据,所以如果在三分钟内,购买产品的记录数超过10条,数据就会有遗漏。这是没有办法的,所以立马金库的统计数据会比真实的偏少。

四、爬虫代码分析

1. 获取登录cookie

因为产品详情页需要登录,所以我们要先拿到登录的cookie才行。getCookie方法如下:

function getCookie() {
   
    superagent.post('https://www.lmlc.com/user/s/web/logon')
        .type('form')
        .send({
            phone: phone,
            password: password,
            productCode: "LMLC",
            origin: "PC"
        })
        .end(function(err, res) {
   
            if (err) {
                handleErr(err.message);
                return;
            }
            cookie = res.header['set-cookie']; //从response中得到cookie
            emitter.emit("setCookeie");
        })
}

phone和password参数是从命令行里传进来的,就是立马理财用手机号登录的账号和密码。我们用superagent去模拟请求立马理财登录接口:https://www.lmlc.com/user/s/web/logon。传入相应的参数,在回调中,我们拿到header的set-cookie信息,并发出一个setCookeie事件。因为我们设置了监听事件:emitter.on("setCookie", requestData),所以一旦获取cookie,我们就会去执行requestData方法。

2. 理财页ajax的爬取

requestData方法的代码如下:

function requestData() {
   
    superagent.get('https://www.lmlc.com/web/product/product_list?pageSize=100&pageNo=1&type=0')
    .end(function(err,pres){
   
        // 常规的错误处理
        if (err) {
            handleErr(err.message);
            return;
        }
        // 在这里清空数据,避免一个文件被同时写入
        if(clearProd){
            fs.writeFileSync('data/prod.json', JSON.stringify([]));
            clearProd = false;
        }
        let addData = JSON.parse(pres.text).data;
        let formatedAddData = formatData(addData.result);
        let pageUrls = [];
        if(addData.totalPage > 1){
            handleErr('产品个数超过100个!');
            return;
        }
        for(let i=0,len=addData.result.length; i<len; i++){
            if(+new Date() < addData.result[i].buyStartTime){
                if(preIds.indexOf(addData.result[i].id) == -1){
                    preIds.push(addData.result[i].id);
                    setPreId(addData.result[i].buyStartTime, addData.result[i].id);
                }
            }else{
                pageUrls.push('https://www.lmlc.com/web/product/product_detail.html?id=' + addData.result[i].id);
            }
        }
        function setPreId(time, id){
   
            cache[id] = setInterval(function(){
   
                if(time - (+new Date()) < 1000){
                    // 预售产品开始抢购,直接修改爬取频次为1s,防止丢失数据
                    clearInterval(cache[id]);
                    clearInterval(timer);
                    delay = 1000;
                    timer = setInterval(function(){
   
                        requestData();
                    }, delay);
                
  • 9
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要编一个Node.js爬虫并进行登录,需要遵循以下步骤: 1. 安装Node.js和相关依赖库:可以使用npm来安装request、cheerio、superagent等库,这些库可以帮助你发送HTTP请求和解析HTML。 2. 了解登录机制:在进行登录之前,需要了解你要爬取的网站的登录机制,通常网站会使用cookie和session来管理用户登录状态。你需要在请求头中添加cookie和session信息来模拟用户登录状态。 3. 发送登录请求:使用superagent库来发送POST请求,携用户名和密码等登录信息,获取cookie和session信息。 4. 保存cookie和session信息:将获取到的cookie和session信息保存下来,在后续的爬虫请求中使用。 5. 发送爬虫请求:使用request库来发送HTTP请求,通过添加cookie和session信息来模拟用户登录状态,获取需要的数据。 以下是一个简单的Node.js爬虫登录示例代码: ```javascript const request = require('request'); const cheerio = require('cheerio'); const superagent = require('superagent'); // 登录信息 const loginInfo = { username: 'your_username', password: 'your_password' }; // 登录请求地址 const loginUrl = 'http://example.com/login'; // 发送登录请求 superagent.post(loginUrl) .send(loginInfo) .end((err, res) => { // 获取cookie和session信息 const cookie = res.header['set-cookie']; const session = res.body.session; // 保存cookie和session信息 const options = { url: 'http://example.com', headers: { 'Cookie': cookie, 'Session': session } }; // 发送爬虫请求 request(options, (error, response, body) => { const $ = cheerio.load(body); // 解析HTML获取需要的数据 const data = $('h1').text(); console.log(data); }); }); ``` 注意:以上示例代码仅供参考,具体实现方式需要根据网站的登录机制和数据获取方式进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值