casperjs爬虫总结 -- (3) 抓取百度萝莉吧图片

本文详细介绍了如何利用casperjs爬虫工具抓取百度萝莉吧中的图片,涵盖了爬虫的基本步骤和技术要点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 我的casper文件夹结构
|data
--|a.json
--|b.json
|fetch
--|tieba.js
|format
--|tieba.xml
common.js
saveToFile.js


解释:
data文件夹
用来存储爬来的信息,文件格式为json
其中遇到图片信息,一律用base64来储存


fetch文件夹
用来放置针对某个页面的抓取规则
因为我们以后可以要抓取别的网站的信息,而他们的dom结构是不一样的


format文件夹
记录以下dom结构,笔记而已,可以忽略


common.js
一般的casper实例的生成,以及其抓取信息的一般流程


saveToFile.js
把信息保存到data文件夹下


2 common.js(重点解释)
代码以及注释
/*
首先来看下我们的使用方式
casperjs ./casper/common.js --url="http://tieba.baidu.com/f?kw=%D0%A1%C2%DC%C0%F2&fr=index" --category=dino --fetch=tieba
*/

// 生成casper的实例
// verbose默认值为false,即不输出来自phantom的信息(请记住,casper是基于phantom的)
// logLevel表示何种级别输出信息,枚举为debug, info, warning, error
var casper = require('casper').create({
    verbose: true,
    logLevel: 'error'
});




// 读取命令行的参数
var url = casper.cli.get("url"),
	fetch = casper.cli.get("fetch"),
	category = casper.cli.get("category");


// console.log(url);
// console.log(fetch);
// console.log(category);


// casper.exit();


var opts = {
	url : casper.cli.get("url"),
	fetch : casper.cli.get("fetch"),
	category : casper.cli.get("category")
};


// 用来计算时间
var startTime, endTime;


// start中可以什么都不写
casper.start();


// 这句很重要,如果没有设置userAgent,则很多website会拒绝访问
var userAgentString = 'Mozilla/5.0 (Macintosh; Intel Mac OS X)';
casper.userAgent(userAgentString);


// 定义"保存数据"事件
// 数据捕获完毕,则保存到文件中
casper.on("saveData",function(data){
	var category = data.category,
		fetchList = data.fetchList;
	var saveToFile = require("./saveToFile");
	var json = JSON.stringify(fetchList,undefined,2);
	saveToFile("./casper/data/"+category+".json",json);
});


// 记录开始时间
casper.then(function(){startTime = + new Date;});


// 使用fetch文件夹中相对应的方法去捕获信息
casper.then(function(){
	require("./fetch/"+fetch).call(casper,opts);
});


// 记录结束时间
casper.then(function(){endTime = + new Date;});


// 打印消耗的时间,单位分钟
casper.then(function() {
	var mins = Math.floor((endTime - startTime) / 60 / 100)/10;
	this.echo(mins+" mins");
});


casper.run();



3 fetch/tieba.js

var _ = require("underscore");


// 贴吧的捕获分为2步
// 第一步浏览列表页,获取各个详情页的"标题"和"链接"
module.exports = function(opts){
	// list 储存各个详情页的"标题"和"链接"
	// fetchList 储存捕获来的信息
	var list,fetchList;
	// 遍历列表
	this.thenOpen(opts.url,function(){
		list = this.evaluate(function(){
			// 沙箱里面不能用_,只能用for,因为_不能传入沙箱
			var aString = "a.j_th_tit";
			var rst = [];
			var nodeList =  document.querySelectorAll(aString);
			for (var i = 0; i < nodeList.length; i++) {
				var node = nodeList[i];
				var title = node.innerHTML;
				var url = node.getAttribute("href");
				if(url.indexOf("http://")==-1){
					url = location.origin+url;
				}
				rst.push({title:title,url:url});
			};
			return rst;
		});
	});


	this.then(function(){
		this.echo("list length:"+list.length);
		this.echo("list -> ");
	});


	this.then(function(){
		fetchList = [];
		var index = 0;
		// 遍历列表中各个链接,去捕获消息
		_.each(list,function(li){
			this.thenOpen(li.url,function(li){
				var rst = this.evaluate(function(opts){
					var domain = location.origin;
					// 发帖人
					var userNameNode = document.querySelector(".p_postlist .l_post .d_author .p_author_name");
					var userName = userNameNode ? userNameNode.innerHTML : "err userName";


					// 发帖时间
					var postTimeNode = document.querySelector(".p_postlist .l_post .d_post_content_firstfloor .core_reply .post-tail-wrap>.tail-info:last-child");
					var postTime =postTimeNode ? postTimeNode.innerHTML : "err postTime";
					
					// 图片
					var imgs = document.querySelectorAll(".p_postlist .d_post_content_firstfloor .p_content .BDE_Image");				
					var imgUrls = [];
					for (var i = 0; i < imgs.length; i++) {
						var imgSrc = imgs[i].getAttribute("src");
						if(imgSrc.indexOf("http://") == -1){
							imgSrc = domain+imgSrc;
						}
						imgUrls.push(imgSrc);
					};
					return {
						url:opts.url,
						title:opts.title,
						userName:userName ,
						postTime:postTime,
						imgUrls:imgUrls
					};
				// 简单原始的对象li可以被注入 
				},li);
				
				// 把imgurl转成img的base64				
				this.then(function(){
					var imgCodes = [];
					_.each(rst.imgUrls,function(imgUrl){
						this.thenOpen(imgUrl,function(imgUrl){
							var imgCode = this.base64encode(imgUrl);
							imgCodes.push(imgCode);
						}.bind(this,imgUrl));
					}.bind(this));
					this.then(function(){
						rst.imgCodes = imgCodes;
					});
				});


				this.echo(index+": "+this.getCurrentUrl());
				index++;
				fetchList.push(rst);
			}.bind(this,li));
		}.bind(this));
	});


	this.then(function(){
		// save to file
		var category = opts.category;
		this.emit("saveData",{category:category,fetchList:fetchList});
	});
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值