功能:从天涯帖子中下载楼主发言到一个文本文件中

实验对象:http://bbs.tianya.cn/post-no05-308123-1.shtml  《鹿鼎记中计》 柳成萌著

爬取效果:除第一个贴需要手动下载外,其它均可自动完成,并有断点续传功能。

爬取结果下载:https://files.cnblogs.com/files/xiandedanteng/ludingjizhongji.zip   这是篇好文章,值得一读。

代码:

//======================================================
// 天涯帖子下载爬虫1.00
// 目标:http://bbs.tianya.cn/post-no05-308123-1.shtml
// 2018年3月22日
//======================================================// 内置https模块
var https=require("https");// 内置http模块
var http=require("http");// 用于解析gzip网页(ungzip,https得到的网页是用gzip进行压缩的)
var zlib = require('zlib'); // 内置文件处理模块,用于创建目录和图片文件
var fs=require('fs');// 用于转码。非Utf8的网页如gb2132会有乱码问题,需要iconv将其转码
var iconv = require('iconv-lite');// cheerio模块,提供了类似jQuery的功能,用于从HTML code中查找图片地址和下一页
var cheerio = require("cheerio");// 请求参数,JSON格式,http和https都有使用
var options;// request请求
var req;// 数据数组,找到的帖子时间和内容会放到这里
var datas=[];//--------------------------------------
// 爬取网页,找帖子内容,再爬
// pageUrl sample:http://bbs.tianya.cn/post-no05-308123-1.shtml
//--------------------------------------
function crawl(pageUrl){console.log("Current page="+pageUrl);// 得到hostname和pathvar currUrl=pageUrl.replace("http://","");var pos=currUrl.indexOf("/");var hostname=currUrl.slice(0,pos);    //console.log("hostname="+hostname);var path=currUrl.slice(pos);    //console.log("path="+path);pos=currUrl.lastIndexOf("/");var dir="http://"+currUrl.slice(0,pos);            //console.log("dir="+dir);// 初始化options  options={hostname:hostname,port:80,path:path,// 子路径method:'GET',        };req=http.request(options,function(resp){var html = [];resp.on("data", function(data) {html.push(data);})resp.on("end", function() {var buffer = Buffer.concat(html);var body = buffer.toString();// http://bbs.tianya.cn/post-no05-308123-1.shtml 无需解码//console.log("body="+body);var $ = cheerio.load(body);        var count=0;// 由于天涯帖子的特殊格式,开篇只好略过,读者请自行添加/*$(".atl-main .atl-item .bbs-content").each(function(index,element){var content=$(element).text();var obj=new Object;obj.user="楼主";obj.time="开篇";obj.content=content;datas.push(obj); count++;})  */// 找帖子内容放入数组$(".atl-item").each(function(index,element){var user=$(element).attr("js_username");//console.log("user="+user);if(user=="柳成萌"){// 柳成荫是楼主IDvar innerHtml=$(element).html();//console.log("innerHtml="+innerHtml);// 找时间var topicTime=null;var $1=cheerio.load(innerHtml); $1(".atl-info span").each(function(index1,element){                        if(index1==1){topicTime=$1(element).text();//console.log("topicTime="+topicTime);
                        }});// 找内容var topicContent=null;//var $1=cheerio.load(innerHtml); $1(".bbs-content").each(function(index1,element){topicContent=$1(element).text().trim();//console.log("topicContent="+topicContent);
                    });// 内容和时间都找到了再放入数组if(topicTime!=null && topicContent!=null){// 先看有没有var isFound=false;for(var i=0;i<datas.length;i++){var value=datas[i];if(value.time==topicTime){isFound=true;break;}}// 没有再往里放if(isFound==false){var obj=new Object;obj.user=user;obj.time=topicTime;obj.content=topicContent;datas.push(obj); console.log("user="+obj.user+" "+obj.time);    count++;}                        }}})   console.log("找到帖子"+count+"条.");                // 找下一页var nextPageUrl=null;            $(".js-keyboard-next").each(function(index,element){var text=$(element).text();if(text.indexOf('下页')!=-1){nextPageUrl=dir+$(element).attr("href");//console.log("找到下一页.="+nextPageUrl);
                }       })if(nextPageUrl==null){console.log(pageUrl+"已经是最后一页了.\n");saveFile(pageUrl,datas);// 保存
                download(datas);}else{console.log("继续下一页");crawl(nextPageUrl);}       }).on("error", function() {saveFile(pageUrl,datas);// 保存console.log("crawl函数失败,请进入断点续传模式继续进行");})});// 超时处理req.setTimeout(7500,function(){req.abort();});// 出错处理req.on('error',function(err){console.log('请求发生错误'+err);  saveFile(pageUrl,datas);// 保存console.log("crawl函数失败,请进入断点续传模式继续进行");});// 请求结束
    req.end();
}//--------------------------------------
// 下载内容
//--------------------------------------
function download(datas){var total=datas.length;console.log("总计有"+total+"条帖子将被下载.");// 合并内容var space = '____';var newLine = '\n';var chunks = [];var length = 0;for(var i=0;i<datas.length;i++){var data=datas[i];var value = space+data.content+newLine;// data.time也可以加入var buffer = new Buffer(value);chunks.push(buffer);length += buffer.length;}var resultBuffer = new Buffer(length);for(var i=0,size=chunks.length,pos=0;i<size;i++){chunks[i].copy(resultBuffer,pos);pos += chunks[i].length;}// 写入文件var fileName='result'+getNowFormatDate()+".txt";fs.appendFile('./'+fileName, resultBuffer, function (err) {if(err){console.log("不能写入文件"+fileName);console.log(err);}});console.log("写入文件"+fileName+"完成");
}//--------------------------------------
// 取得当前时间
//--------------------------------------
function getNowFormatDate() {var date = new Date();var seperator1 = "-";var seperator2 = "_";var month = date.getMonth() + 1;var strDate = date.getDate();if (month >= 1 && month <= 9) {month = "0" + month;}if (strDate >= 0 && strDate <= 9) {strDate = "0" + strDate;}var currentdate =date.getFullYear() + seperator1 + month + seperator1 + strDate+ " " + date.getHours() + seperator2 + date.getMinutes()+ seperator2 + date.getSeconds();return currentdate;
}//--------------------------------------
// 程序入口
//--------------------------------------
function getInput(){process.stdin.resume();    process.stdout.write("\033[33m 新建模式输入第一页URL,断点续传模式输入0,请输入: \033[39m");// 草黄色process.stdin.setEncoding('utf8');process.stdin.on('data',function(text){var input=text.trim();process.stdin.end();// 退出输入状态    if(text.trim()=='0'){process.stdout.write("\033[36m 进入断点续传模式. \033[39m");    // 蓝绿色// Read Filefs.readFile('./save.dat','utf8',function(err,data){if(err){console.log('读取文件save.dat失败,因为'+err);}else{//console.log(data);var obj=JSON.parse(data);datas=obj.datas;console.log('提取原有数据'+datas.length+'条');crawl(obj.url);        }});// Resume crawl}else{process.stdout.write("\033[35m 进入新建模式. \033[039m");    //紫色
crawl(input);            }});
}//--------------------------------------
// 将爬行中信息存入数据文件
//--------------------------------------
function saveFile(url,datas){var obj=new Object;obj.url=url;obj.datas=datas;var text=JSON.stringify(obj);fs.writeFile('./save.dat',text,function(err){if(err){console.log('写入文件save.dat失败,因为'+err);}});
}// 调用getInput函数,程序开始
getInput();

下载文本截图:

转载于:https://www.cnblogs.com/xiandedanteng/p/8637242.html

Nodejs 天涯帖子《鹿鼎记中计》 柳成萌著 下载爬虫相关推荐

  1. scrapy爬取天涯帖子内容

    主要代码 import scrapy from scrapy import Selector from first.items import TYItem import reclass TianyaS ...

  2. ruby + nokogiri实现将天涯易读全帖转换成txt文件的功能

    YiduFreeTxt 0.1beta版发布 天涯易读网站原本是有提供下载全帖txt版本的功能的,但是该功能需要易读积分,这对于从来不登陆易读的笔者来说,无疑是一件不可能完成的任务. 于是随手写了个免 ...

  3. python 抓取天涯帖子内容并保存

    python 抓取天涯帖子内容并保存 作者:大捷龙 csdn : http://blog.csdn.net/koanzhongxue ** 分析:天涯的帖子下载可以分为以下几个步骤 手动传入一个帖子首 ...

  4. 2019 此去经年,才无尽,计未成,世如星辰

    2019 已是最后一天,近几年已经习惯性地在年底写点什么,记录一下这一年的心得体会,大概也算不得总结,算是一次简短的回眸一顾. 世如星辰 有时觉着这一年又一年,就如这天上星辰,似乎每年都差不多,却又每 ...

  5. java代码二进制转为十六进制_Java 中二进制转换成十六进制的两种实现方法

    Java 中二进制转换成十六进制的两种实现方法 每个字节转成16进制,方法1 /** * 每个字节转成16进制,方法1 * * @param result */ private static Stri ...

  6. IDEA中快捷键修改成和eclipse一样

    为了在使用eclipse后,更好的使用IDEA,或者在同时使用两个软件时候更好的提高开发效率,所以需要将IDEA中快捷键修改成和eclipse一样. 方式一: 方式二: 选择后点击ok(文章末尾有网盘 ...

  7. C# 中DataTable转成模型List

    C# 中DataTable转成模型List 引入using System.Reflection; 命名空间 使用注意实体类的属性名必须和DataTable的列名一致 使用: DBList<Sto ...

  8. python合并txt文本_Python实现将目录中TXT合并成一个大TXT文件的方法

    本文实例讲述了Python实现将目录中TXT合并成一个大TXT文件的方法.分享给大家供大家参考.具体如下: 在网上下了一个dota的英雄攻略,TXT格式,每个英雄一个文件,看得疼,就写了一个小东西,合 ...

  9. android图片分割点击,Android中图片切割成多个图片的实现方法

    系统手机总是有很多不是很完美的时候,比如逐帧播放图片的时候产生的效果,今天爱站技术频道小编为大家整理了Android中图片切割成多个图片的实现方法,大家一起来了解一下吧! 以下是封装好的两个类,可以实 ...

最新文章

  1. Hadoop(十五)MapReduce程序实例
  2. UIRemoteNotificationType 参考
  3. 讨论了好久的问题,IE、Firefox下CSS图片垂直居中的问题
  4. 大侦探福老师——幽灵Crash谜踪案
  5. ATL offsetofclass 的工作原理
  6. 不分享“年度报告”的人,多少有点难言之隐
  7. 反装逼指南:掀起机器学习的神秘面纱
  8. 高性能地图服务器,电子地图的背后—超速海量Xeon5500机架服务器
  9. matlab中投影,MATLAB在极射赤平投影中的应用
  10. ajax跨域,json,jsonp
  11. Android SDK Manager设置HTTP Proxy Server代理服务器
  12. 5.8G雷达感应模块,微波雷达传感器技术,人体存在感应雷达
  13. YIT-CTF—隐写术
  14. TDD实践之实用主义
  15. 计算机信息心得体会作文50字,考试感想作文50字5篇
  16. java多线程心法(基础概念)
  17. c语言输入字符串 48CT,2004年9月全国计算机等级考试二级C笔试试题含答案
  18. 基于Vue移动音乐webapp跨域获取QQ音乐歌单接口
  19. KKS1(生产订单计算-计算差异)时 常见差异问题
  20. BZOJ1616: [Usaco2008 Mar]Cow Travelling游荡的奶牛

热门文章

  1. Android 更改EditText下划线的颜色样式
  2. 简单XMLSAX解析
  3. 理解操作系统的进程的概念就如吃饭一样简单
  4. css hover遮罩层效果
  5. 蓝桥杯—图形排版—暴力破解
  6. 英超-巴拉克首演兰帕德破僵局 切尔西2球复仇劲敌
  7. android arrayadapter自定义,Android零基础入门|自定义ArrayAdapter
  8. VueUse——一个提升开发效率的Vue3工具库,让你早早下班
  9. 将查询到的数据库数据显示到html页面
  10. .net中的动态时钟 (年月日 时分秒)