这里做得比较暴力,没有分页取出数据解析,O(∩_∩)O哈哈~,居然没有被挂机.不过解析的坑特别多...不过大部分我想要的数据都拿到了.

//解析列表数据
var http = require("http"),
cheerio = require("cheerio"),
mongoose = require('mongoose'),
db = mongoose.createConnection('mongodb://127.0.0.1:27017/crawl58'); db.on('error', function (error) {
console.log('mongodb连接错误: ' + error);
}); //列表页面数据
var mongooseSchema = new mongoose.Schema({
url: {type: String},//抓取地址
type: {type: String},//类型
content: {type: String},//抓取地址
updateTime: {type: Date, default: Date.now},//数据抓取时间
flag: {type: String, default: 0} //用于判断是否抓取过 0表示详情没有抓取过.
});
// model
var mongooseModel = db.model('pageList', mongooseSchema);//代理记账 //存储数据
var parseListSchema = new mongoose.Schema({
url: {type: String},//抓取地址
detailUrl: {type: String},//详情地址
type: {type: String},//类型
title: {type: String},//标题
company: {type: String},//公司名称
contact: {type: String},//联系人
score: {type: String},//评分
phone: {type: String},//电话
updateTime: {type: Date, default: Date.now},//数据解析时间
flag: {type: String, default: 0} //用于判断是否抓取过 0表示详情没有抓取过.
});
// model
var parseListModel = db.model('parseList', parseListSchema);//代理记账 var pageNo = 0;
var data;//保存取出的数据
function queryList() {
var condition = {
url: 'http://cd.58.com/yanzi/pn16/?PGTID=139112794188694845657499716&ClickID=1'
}
mongooseModel.find(condition, function (error, result) {
if (error) {
console.log(error);
} else {
//解析数据
data = result;
console.log('开始解析...');
parseList();
}
});//.skip(0).limit(100);//分页解析
}; //解析
function parseList() {
//解析数据并存入数据库
if (!data[pageNo]) {
console.log('解析完成. 页码: ' + pageNo);
//更新数据库,修改解析标志位 暂时不处理. return false;
}
var listItem = data[pageNo];
var listContent = listItem.content;
if (!listContent) {
pageNo = pageNo + 1;
parseList();
return false;
}
var $ = cheerio.load(listContent); //解析页面
var trElements = $('.small-tbimg>tr');
var docArray = [];
trElements.each(function (index, ele) {
if ($(ele).find('td.dev').length > 0) {
//已经没有这个类型的数据了.
return false;
}
var contact = $(ele).find('div.tdiv .f14').first().text();
if (contact) {
contact = contact.replace(':', '');
} var title = $(ele).find('div.tdiv>a').first().text(); var company = $(ele).find('a.u').first().text();
if (!company) {
var companyBox = $(ele).find('div.tdiv');
companyBox.find('b,a,span,i').remove();
company = decodeUtf8(companyBox.html());
if (company && company.indexOf('<br>') > 0) {
company = company.replace('company', '').replace('%uA0', '');
company = company.split('<br>')[2];
}
} var score = $(ele).find('.star00').first().attr('title'); var detailUrl = $(ele).find('div.pjdiv a').first().attr('href');
if (!detailUrl) {
detailUrl = $(ele).find('div.tdiv a').first().attr('href');
if (!detailUrl) {
detailUrl = $(ele).find('a.t').first().attr('href');
}
} else {
detailUrl = detailUrl.replace('showtype=yuyue&', '');
} var phone = $(ele).find('.jumpDiv_tel').first().text();
if (phone) {
phone = getNumber(phone);
}
var item = {
contact: contact,
type: listItem.type,
title: title,
url: listItem.url,
detailUrl: detailUrl,
company: company,
score: score,
phone: phone
};
docArray.push(item);
}); //存入数据库
parseListModel.create(docArray, function (error) {
if (error) {
console.log(error);
} else {
console.log('保存成功 页码: ' + pageNo + ' 条数: ' + docArray.length);
pageNo = pageNo + 1;
parseList();
}
});
}; //解码utf-8
function decodeUtf8(str) {
return unescape(str.replace(/&#x/g, '%u').replace(/;/g, ''))
}; //提取电话号码
function getNumber(str) {
var reg = /[0-9][0-9]*/g;
return str.match(reg).join('-');//带区号的电话号码
}; //这里为整个解析的开始 -- 特么这么烂的代码自己都看不下去了,唯一看得过去的是,能用 .O(∩_∩)O.
//调用...1.取出数据;2 解析数据并存入数据库
queryList();

nodejs抓取数据二(列表解析)的更多相关文章

  1. nodejs抓取数据一(列表抓取)

    纯属初学...有很多需要改进的地方,请多多指点... 目标是抓取58同城 这个大分类下的列表数据: http://cd.58.com/caishui/?PGTID=14397169455980.924 ...

  2. PHP获取cookie、Token、模拟登录、抓取数据、解析生成json

    本文介绍使用PHP获取cookie,获取Token.以及模拟登录.然后抓取数据.最后解析生成json的的过程. 0. 设置Cookie路径 set_time_limit(0); //使用的cookie ...

  3. C# 微信 生活助手 空气质量 天气预报等 效果展示 数据抓取 (二)

    此文主要是 中国天气网和中国环境监测总站的数据抓取 打算开放全部数据抓取源代码 已在服务器上 稳定运行半个月 webapi http://api.xuzhiheng.cn/ 常量 /// <su ...

  4. NET 5 爬虫框架/抓取数据

    爬虫大家或多或少的都应该接触过的,爬虫有风险,抓数需谨慎.  爬虫有的是抓请求,有的是抓网页再解析 本着研究学习的目的,记录一下在 .NET Core 下抓取数据的实际案例.爬虫代码一般具有时效性,当 ...

  5. nodejs--实现跨域抓取数据

    最近公司安排给我一个任务,抓取页面数据:http://survey.finance.sina.com.cn/static/20205/20131120.html?pid=20205&dpc=1 ...

  6. java抓取网页数据,登录之后抓取数据。

    最近做了一个从网络上抓取数据的一个小程序.主要关于信贷方面,收集的一些黑名单网站,从该网站上抓取到自己系统中. 也找了一些资料,觉得没有一个很好的,全面的例子.因此在这里做个笔记提醒自己. 首先需要一 ...

  7. 爬虫学习笔记(1)-- 利用Python从网页抓取数据

    最近想从一个网站上下载资源,懒得一个个的点击下载了,想写一个爬虫把程序全部下载下来,在这里做一个简单的记录 Python的基础语法在这里就不多做叙述了,黑马程序员上有一个基础的视频教学,可以跟着学习一 ...

  8. 分布式爬虫:使用Scrapy抓取数据

    分布式爬虫:使用Scrapy抓取数据 Scrapy是Python开发的一个快速,高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据.Scrapy用途广泛,可以用于数据挖掘. ...

  9. web scraper 抓取数据并做简单数据分析

    其实 web scraper 说到底就是那点儿东西,所有的网站都是大同小异,但是都还不同.这也是好多同学总是遇到问题的原因.因为没有统一的模板可用,需要理解了 web scraper 的原理并且对目标 ...

随机推荐

  1. java Future模式

    Java多线程编程中,常用的多线程设计模式包括:Future模式.Master-Worker模式.Guarded Suspeionsion模式.不变模式和生产者-消费者模式等.这篇文章主要讲述Futu ...

  2. HDU - 4994 Revenge of Nim (取石子游戏)

    Problem Description Nim is a mathematical game of strategy in which two players take turns removing ...

  3. Cacti安装详细步骤(转)

    一.cacti概述 1. cacti是用php语言实现的一个软件,它的主要功能是用snmp服务获取数据,然后用rrdtool储存和更新数据,当用户需要查看数据的时候用rrdtool生成图表呈现给用户. ...

  4. make -jN

    今天又一次尝试编译安卓,想测试一下编译的速度如何? 考虑机器是4核8线程,就用上了 make -j8,感觉上上速度是很快,刷屏就下来了,不过错误了,错误的提示大概是某个文件的规则没找到,想想了多线程并 ...

  5. PopupWindow组件的使用问题

    //如果默认屏幕的话,父view就写自己 popupWindow.showAtLocation(inflate, Gravity.BOTTOM, 0, 0); PopupWindow 顾名思义为弹出式 ...

  6. UITableviewCell 重用内存

    转载自:http://www.cnblogs.com/tangbinblog/p/3371545.html 重用实现分析 查看UITableView头文件,会找到NSMutableArray*  vi ...

  7. android 修改listview item view 的方法(转)

    android 修改listview item view 的方法   具体的解答办法很简单: 代码如下 : 1.获取需要更新的view int visiblePosition = mListView. ...

  8. FZU Problem 2150 Fire Game(bfs)

    这个题真要好好说一下了,比赛的时候怎么过都过不了,压点总是出错(vis应该初始化为inf,但是我初始化成了-1....),wa了n次,后来想到完全可以避免这个问题,只要入队列的时候判断一下就行了. 由 ...

  9. 基于js脚本的单机黄金点游戏

    题目描述 N个同学(N通常大于10),每人写一个0-100之间的有理数 (不包括0或100),交给裁判,裁判算出所有数字的平均值,然后乘以0.618(所谓黄金分割常数),得到G值.提交的数字最靠近G( ...

  10. JAVA基础--方法的重写overwrite 和 重载overload

    重写 overwrite或者override: 相同的方法名称, 参数列表和返回类型 重载overload: 方法有相同的名字, 但是参数不同 (参数个数不同, 参数类型不同, 其中一个不同即可), ...