From aadc66ba31c189004aba99604333e830eb4d9fe7 Mon Sep 17 00:00:00 2001 From: fengkx Date: Sun, 12 May 2019 23:55:53 +0800 Subject: [PATCH] fix natgeo (page structure change) (#2111) * fix natgeo (page structure change) * add cache --- docs/travel.md | 2 +- lib/router.js | 1 - lib/routes/natgeo/natgeo.js | 82 ++++++++++++++++++++++++++----------- 3 files changed, 60 insertions(+), 25 deletions(-) diff --git a/docs/travel.md b/docs/travel.md index 49feb8cc47..675ae6eabe 100644 --- a/docs/travel.md +++ b/docs/travel.md @@ -37,7 +37,7 @@ IATA 国际航空运输协会机场代码, 参见[维基百科 国际航空运 ## 国家地理 - + ## 马蜂窝 diff --git a/lib/router.js b/lib/router.js index 461f5469c8..4efe0f70ee 100644 --- a/lib/router.js +++ b/lib/router.js @@ -422,7 +422,6 @@ router.get('/sexinsex/:id/:type?', require('./routes/sexinsex/index')); router.get('/gcores/category/:category', require('./routes/gcores/category')); // 国家地理 -router.get('/natgeo/dailyphoto', require('./routes/natgeo/dailyphoto')); router.get('/natgeo/:cat/:type?', require('./routes/natgeo/natgeo')); // 一个 diff --git a/lib/routes/natgeo/natgeo.js b/lib/routes/natgeo/natgeo.js index aca53ed352..9113e0ae09 100644 --- a/lib/routes/natgeo/natgeo.js +++ b/lib/routes/natgeo/natgeo.js @@ -1,40 +1,76 @@ const cheerio = require('cheerio'); const axios = require('../../utils/axios'); +// https://www.natgeomedia.com//article/ + +const MonthMap = { + JAN: 0, + FEB: 1, + MAR: 2, + APR: 3, + MAY: 4, + JUN: 5, + JUL: 6, + AUG: 7, + SEP: 8, + OCT: 9, + NOV: 10, + DEC: 11, +}; + +async function load(link) { + const { data } = await axios.get(link); + const $ = cheerio.load(data); + const dtStr = $('.content-title-area') + .find('h6') + .first() + .text() + .split(/[\s.]+/); + const dt = new Date(); + dt.setMonth(MonthMap[dtStr[0].toUpperCase()]); + dt.setDate(dtStr[1]); + let description = + $('article') + .first() + .html() + + $('article') + .eq(1) + .html(); + if (/photo/.test(link)) { + description = $('#content-album').html() + description; + } + return { + title: $('title').text(), + pubDate: dt.toUTCString(), + description, + }; +} + module.exports = async (ctx) => { - const type = `${ctx.params.type ? ctx.params.type : ''}`; - const url = `https://www.natgeomedia.com/category/${ctx.params.cat}/${type}`; + const type = `${ctx.params.type || ''}`; + const url = `https://www.natgeomedia.com/${ctx.params.cat}/${type}`; const res = await axios.get(url); const $ = cheerio.load(res.data); - const list = $('.td-ss-main-content').find('.td-animation-stack'); + const urlList = Array.prototype.map.call($('.article-link-w100').find('.read-btn'), (i) => + $(i) + .find('a[href]') + .first() + .attr('href') + ); const count = []; - for (let i = 0; i < Math.min(list.length, 10); i++) { + for (let i = 0; i < Math.min(urlList.length, 10); i++) { count.push(i); } const out = await Promise.all( count.map(async (i) => { - const each = $(list[i]); - const storyLink = each.find('a[itemprop=url]').attr('href'); - const item = { - title: each.find('a[itemprop=url]').attr('title'), - pubDate: each.find('time').attr('datetime'), - link: storyLink, - guid: storyLink.match(/\d+/g)[0], + const link = urlList[i]; + const single = { + link, }; - const key = `${ctx.params.cat}${type}${item.guid}`; - const value = await ctx.cache.get(key); - if (value) { - item.description = value; - } else { - const storyDetail = await axios.get(item.link); - const data = storyDetail.data; - const $ = cheerio.load(data); - item.description = $('.td-post-content').html(); - ctx.cache.set(key, item.description); - } - return Promise.resolve(item); + const other = await ctx.cache.tryGet(link, async () => await load(link)); + return Object.assign({}, single, other); }) ); ctx.state.data = {