前言

因为自己写的demo需要历史天气的统计数据,但是国内很难找到免费的api接口,很多都需要付费和审核。而国外的网站虽然免费但需要提前知道观测站,城市id等信息。所以就有了这么一篇文章的诞生。


准备工作

作用
superagent 发送请求
superagent-charset 设置请求的编码
cheerio 让解析html文档像jquery一样简单

实现思路

  1. 找到目标网站
    东方天气网(本文以此为例)
    天气网
  2. 分析网站结构
    通过分析,可以绘制如下流程图
Created with Raphaël 2.1.2访问基址(异步),拿到城市的根地址按城市和年月拼成新的地址访问新地址(异步)拿到城市在指定月的数据处理数据
  1. 代码编写思路
    从流程图可以看出,需要先异步请求基址拿到城市的根地址。
    拿到根地址后拼接时间和城市,接着异步访问才能拿到我们要的数据。
    这种嵌套异步可以使用Promise来实现(eventProxy基本已不用)。
  2. 代码实例
var express = require('express');
var router = express.Router();
var superagent = require("superagent");
var charset = require("superagent-charset");    //解决编码问题
var cheerio = require("cheerio");/* GET users listing. */
var mysql = require("mysql");
var responseJson = require("../util/responseJson"); //导入mysql模块
var dbConfig = require("../db/DBconfig");//使用DBConfig.js的配置信息创建一个MySQL连接池
var pool = mysql.createPool(dbConfig.mysql);charset(superagent); //需要遍历的信息
var BaseUrl = "http://tianqi.eastday.com";
var Cities = ["成都"]; //需要获取的城市
var indexArr = ['cd'];
var Years = ["2018"]; //年份,因为2018年以前dom结构不一样,所以这里只取2018
var Months = ["01", "02", "03", "04", "05", "06", "07", "08"]; //月份function getCityUrl (city) {//返回Promisereturn new Promise((resolve, reject) => {superagent.get(BaseUrl + "/history.html").charset("utf-8").end((err, sres) => {if (err) {next(err);return;}let $ = cheerio.load(sres.text);//后续继续遍历的基址let href = $(".letter-box").find("a[title='" + city + "']").attr("href");resolve(href);});})
}//获取指定城市在指定时间的数据
function getData (href, city) {let year = Years[0];return  Months.map(month => {let url = BaseUrl + href.replace(".html", "_" + year + month + '.html' );//获取天气数据return new Promise((resolve, reject1) =>{superagent.get(url).charset("utf-8").end((err1, sres1) => {if (err1) {reject1(err1);return;}let $ = cheerio.load(sres1.text);let arr = [];$("#weaDetailContainer").find(".weatherInfo-item").each((index, item) => {let $item = $(item);arr.push({time: year + "-" + month + "-" + $item.find(".dateBox").text().substr(0, 2),wea: $item.find(".weather-name").text(),tempL: $item.find(".low-temp").text(),tempH: $item.find(".high-temp").text(),wind: $item.find(".wind").text(),});});resolve(arr);});});});
}function dispatch(groups) {var results = []return (function () {var fun = arguments.callee, group = groups.shift()if (!group) {return Promise.resolve(results)}var promises = []group.forEach(function (task) {promises.push(Promise.resolve(task))})return Promise.all(promises).then(function (rets) {results.push(rets)return fun()})}())
} function query (sql) {return new Promise((resolve, reject) => {pool.getConnection((err, conn) => {if(err){reject(err);} else {conn.query(sql, (err1, rows, fields) => {conn.release();if(err1){reject(err1);} else {resolve({rows: rows,fields: fields});}});}});});
}function makeSql (item, index) {let sql = "INSERT INTO weather_" + indexArr[index] + " (time, wea, tempH, tempL, wind) values ";let arr = [].concat.apply([], item);arr.map(group => {sql += "('"+ group.time + "', '"+ group.wea + "', '"+ group.tempH + "', '"+ group.tempL + "', '"+ group.wind+ "'),";});return sql.substring(0, sql.length-1);
} router.get('/', function(req, res, next) {let promiseArr = [];promiseArr = Cities.map(city => {//遍历城市return getCityUrl(city);});Promise.all(promiseArr).then(hrefArr => {return hrefArr.map(href => {return getData(href);});}).then(arr => {return dispatch(arr);}).then(data => {let arr = data.map((item, index) => {return query(makeSql(item, index))});Promise.all(arr).then(() => {res.json({status: true,msg: 'success'})}).catch(e => {res.json({status: false,msg: e.message})})}).catch(e => {res.send(e.message);});
});module.exports = router;

不足

虽然能够实现需求,但是感觉我的Promise在这里用着好像挺乱,没有完全解决嵌套问题。后续会增进学习,对这一部分更加完善。也希望大家能够给出宝贵意见~~

Express + Node 爬取网站数据相关推荐

  1. node爬取app数据_从零开始写一个node爬虫(上)—— 数据采集篇

    爬虫相信大家都知道,这里我们从一个空的文件夹开始,也来写一写我们自己的爬虫程序吧. github入口 下一篇--数据分析篇入口 爬虫毕竟涉及到数据的爬取,所以其实有一个道德的约束,那就是Robots协 ...

  2. 利用linux curl爬取网站数据

    看到一个看球网站的以下截图红色框数据,想爬取下来,通常爬取网站数据一般都会从java或者python爬取,但本人这两个都不会,只会shell脚本,于是硬着头皮试一下用shell爬取,方法很笨重,但旨在 ...

  3. 如何利用python爬取网站数据

    Python是一种非常适合用于网络爬虫的编程语言,以下是Python爬取网站数据的步骤: 1. 确定目标网站和所需数据:首先要找到需要爬取数据的网站,确定你需要爬取的数据是哪一部分. 2. 发送请求: ...

  4. 使用python爬取网站数据并写入到excel中

    文章目录 前言 一.使用python爬取网上数据并写入到excel中 例子一: 例子二: 二.工具类 总结 前言 记录一下使用python将网页上的数据写入到excel中 一.使用python爬取网上 ...

  5. 用Excel,只需30秒就可爬取网站数据

    是的,你没看错,就是用Excel爬数据.那么为什么要用它呢?因为它不需要写一行代码,只需要轻轻点几下鼠标,就可以得到你想要的数据,全程30秒左右就能搞定,在网站结构简单,需求比较简单的情况下,你只此一 ...

  6. python爬取网站数据(含代码和讲解)

    提示:本次爬取是利用xpath进行,按文章的顺序走就OK的: 文章目录 前言 一.数据采集的准备 1.观察url规律 2.设定爬取位置和路径(xpath) 二.数据采集 1. 建立存放数据的dataf ...

  7. Pycharm + python 爬虫简单爬取网站数据

    本文主要介绍简单的写一个爬取网站图片并将图片下载的python爬虫示例. 首先,python爬虫爬取数据,需要先了解工具包requests以及BeautifulSoup requests中文文档:ht ...

  8. 用Excel,爬取网站数据

    0. 软件版本要求及先决条件 要求1 :Excel2016及以上版本,开箱即用.当然其他低版本,不是不可以,只是需要自己安装插件,爱折腾的可以自己尝试. 要求2:仅支持get请求(这一点不了解的人可以 ...

  9. #python学习笔记#使用python爬取网站数据并保存到数据库

    上篇说到如何使用python通过提取网页元素抓取网站数据并导出到excel中,今天就来说说如何通过获取json爬取数据并且保存到mysql数据库中. 本文主要涉及到三个知识点: 1.通过抓包工具获取网 ...

最新文章

  1. html 设置打印区域,excel打印区域怎么设置
  2. linux cordova安装教程,mac怎么安装cordova?
  3. SAP License:SAP IDES常用功能及测试环境
  4. Android 高效调试神器 JRebel
  5. 为RecyclerView打造通用Adapter
  6. MATLAB图像处理:一分钟去除图片中的雾霾
  7. LitePal操作数据库
  8. Sqlmap命令讲解
  9. 洛谷1498-谢尔宾斯基三角形-python-(递归)
  10. 80286计算机配置,电脑的各种配置给详的细解释.doc
  11. matlab 求余函数mod
  12. 零基础快速入门(二)爬取豆瓣电影——python爬虫实例
  13. p=p->next 是什么意思
  14. js prototype原形
  15. Java 回调函数Callback
  16. AES算法中S盒的FPGA实现
  17. 101. Symmetric Tree (C语言)
  18. Xampp介绍、安装过程及使用方法
  19. 现代控制理论6——能控、能观及其对偶原理、线性变换、结构分解
  20. Excel提取18位/15位身份证出生日期②

热门文章

  1. WEB前端面试题汇总整理01
  2. 每周一书-2016年8月28日到9月4日获奖读者公布
  3. atitit.atiOrmStoreService 框架的原理与设计 part1  概述与新特性
  4. 为easyui添加多条件验证
  5. iOS7时代我们用什么来追踪和识别用户?
  6. jsonrpc aria2_抛弃迅雷,Aria2 新手入门
  7. VMware安装虚拟机并使用NAT模式连接网络
  8. Maven基础及概念
  9. sql排名名次分页mysql_mysql 实现排名及中文排序实例[分页累加行号]
  10. sp烘焙流程_小手雷-PBR材质流程(一)——(基本材质)