日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Express + Node 爬取网站数据

發布時間:2025/3/11 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Express + Node 爬取网站数据 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

因為自己寫的demo需要歷史天氣的統計數據,但是國內很難找到免費的api接口,很多都需要付費和審核。而國外的網站雖然免費但需要提前知道觀測站,城市id等信息。所以就有了這么一篇文章的誕生。


準備工作

作用
superagent發送請求
superagent-charset設置請求的編碼
cheerio讓解析html文檔像jquery一樣簡單


實現思路

  • 找到目標網站
    東方天氣網(本文以此為例)
    天氣網
  • 分析網站結構
    通過分析,可以繪制如下流程圖
  • Created with Rapha?l 2.1.2訪問基址(異步),拿到城市的根地址按城市和年月拼成新的地址訪問新地址(異步)拿到城市在指定月的數據處理數據
  • 代碼編寫思路
    從流程圖可以看出,需要先異步請求基址拿到城市的根地址。
    拿到根地址后拼接時間和城市,接著異步訪問才能拿到我們要的數據。
    這種嵌套異步可以使用Promise來實現(eventProxy基本已不用)。
  • 代碼實例
  • 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 爬取网站数据的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。