Add Hopper (#474)

This commit is contained in:
Henry Wang
2018-08-16 09:48:32 +01:00
committed by DIYgod
parent 1bd45821c0
commit cf54583adc
4 changed files with 118 additions and 3 deletions

View File

@@ -1825,3 +1825,19 @@ nearby: 可选 0 或 1默认 0 为不包括,是否包括临近机场
1. 简单模式例如「data visualization」[https://rsshub.app/google/scholar/data+visualization](https://rsshub.app/google/scholar/data+visualization)。
2. 高级模式,前往 [Google Scholar](https://scholar.google.com/schhp?hl=zh-cn&as_sdt=0,5),点击左上角,选择高级搜索并提交查询。此时 URL 应为:[https://scholar.google.com/scholar?as_q=data+visualization&as_epq=&as_oq=&as_eq=&as_occt=any&as_sauthors=&as_publication=&as_ylo=2018&as_yhi=&hl=zh-CN&as_sdt=0%2C5](https://scholar.google.com/scholar?as_q=data+visualization&as_epq=&as_oq=&as_eq=&as_occt=any&as_sauthors=&as_publication=&as_ylo=2018&as_yhi=&hl=zh-CN&as_sdt=0%2C5),复制`https://scholar.google.com/scholar?`后的所有语句作为本路由的查询参数。例子所对应的完整路由为[https://rsshub.app/google/scholar/as_q=data+visualization&as_epq=&as_oq=&as_eq=&as_occt=any&as_sauthors=&as_publication=&as_ylo=2018&as_yhi=&hl=zh-CN&as_sdt=0%2C5](https://rsshub.app/google/scholar/as_q=data+visualization&as_epq=&as_oq=&as_eq=&as_occt=any&as_sauthors=&as_publication=&as_ylo=2018&as_yhi=&hl=zh-CN&as_sdt=0%2C5)。
## Hopper Flight Deals
### Hopper 特价机票 <Author uid="HenryQW"/>
举例: 伦敦希思罗 &#9992; 北京首都国际 [https://rsshub.app/hopper/LHR/PEK](https://rsshub.app/hopper/LHR/PEK)
路由: `/hopper/:from/:to?`
参数:
from: 始发地IATA 国际航空运输协会机场代码
to: 目的地IATA 国际航空运输协会机场代码,可选,缺省则目的地为`任意城市`
IATA 国际航空运输协会机场代码,参见[维基百科 国际航空运输协会机场代码](<https://zh.wikipedia.org/wiki/%E5%9B%BD%E9%99%85%E8%88%AA%E7%A9%BA%E8%BF%90%E8%BE%93%E5%8D%8F%E4%BC%9A%E6%9C%BA%E5%9C%BA%E4%BB%A3%E7%A0%81_(A)>)

View File

@@ -308,8 +308,11 @@ Eg: [https://rsshub.app/github/issue/DIYgod/RSSHub](https://rsshub.app/github/is
Route: `/github/issue/:user/:repo`
Parameters: user, username
Parameters: repo, repo name
Parameters:
user, username
repo, repo name
## EZTV
@@ -366,7 +369,7 @@ locations: the departing city, consists of an 「ISO 3166-1 country code」 and
1. Origin's ISO 3166-1 country code + city name, eg. `us+new york`, [https://rsshub.app/atfd/us+new york](https://rsshub.app/atfd/us+new%20york)
2. Multiple origins are support via a comma separated string, eg. `us+new york,gb+london`, [https://rsshub.app/atfd/us+new york,gb+london/](https://rsshub.app/atfd/us+new%20york,gb+london/)
For ISO 3166-1 country codes please refer to [wikipedia ISO_3166-1](https://en.wikipedia.org/wiki/ISO_3166-1)
For ISO 3166-1 country codes please refer to [Wikipedia ISO_3166-1](https://en.wikipedia.org/wiki/ISO_3166-1)
nearby: whether includes nearby airports, optional value of 0 or 1, default to 0 (exclude nearby airports)
@@ -389,3 +392,19 @@ Parameters: query, query statement which supports「Basic」and「Advanced」mod
1. Basic mode, sample query is the keywords desired, eg.「data visualization」, [https://rsshub.app/google/scholar/data+visualization](https://rsshub.app/google/scholar/data+visualization).
2. Advanced mode, visit [Google Scholar](https://scholar.google.com/schhp?hl=en&as_sdt=0,5), click the top left corner and select「Advanced Search」, fill in your conditions and submit the search. The URL should look like this: [https://scholar.google.com/scholar?as_q=data+visualization&as_epq=&as_oq=&as_eq=&as_occt=any&as_sauthors=&as_publication=&as_ylo=2018&as_yhi=&hl=en&as_sdt=0%2C5](https://scholar.google.com/scholar?as_q=data+visualization&as_epq=&as_oq=&as_eq=&as_occt=any&as_sauthors=&as_publication=&as_ylo=2018&as_yhi=&hl=en&as_sdt=0%2C5), copy everything after `https://scholar.google.com/scholar?` from the URL and use it as the query for this route. The complete URL for the above example should look like this: [https://rsshub.app/google/scholar/as_q=data+visualization&as_epq=&as_oq=&as_eq=&as_occt=any&as_sauthors=&as_publication=&as_ylo=2018&as_yhi=&hl=en&as_sdt=0%2C5](https://rsshub.app/google/scholar/as_q=data+visualization&as_epq=&as_oq=&as_eq=&as_occt=any&as_sauthors=&as_publication=&as_ylo=2018&as_yhi=&hl=en&as_sdt=0%2C5).
## Hopper
### Hopper Flight Deals <Author uid="HenryQW"/>
Eg: London Heathrow Airport &#9992; Beijing Capital International Airport [https://rsshub.app/hopper/LHR/PEK](https://rsshub.app/hopper/LHR/PEK)
Route: `/hopper/:from/:to?`
Parameters:
from, origin airport IATA code
to, destination airport IATA code, optional, if unset the destination will be set to `anywhere`
For airport IATA code please refer to [Wikipedia List of airports by IATA code](https://en.wikipedia.org/wiki/List_of_airports_by_IATA_code:_A)

View File

@@ -414,4 +414,7 @@ router.get('/fir/update/:id', require('./routes/fir/update'));
// Google
router.get('/google/scholar/:query', require('./routes/google/scholar'));
// Hopper
router.get('/hopper/:from/:to?', require('./routes/hopper/index'));
module.exports = router;

77
routes/hopper/index.js Normal file
View File

@@ -0,0 +1,77 @@
const axios = require('../../utils/axios');
const config = require('../../config');
const cheerio = require('cheerio');
module.exports = async (ctx) => {
const from = ctx.params.from;
const to = ctx.params.to || 'Anywhere';
const url = `https://www.hopper.com/deals/best/from/${from}/to/${to}`;
const title = `Hopper - Flights From ${from} to ${to}`;
const response = await axios({
method: 'get',
url,
headers: {
'User-Agent': config.ua,
},
params: {
pid: 'website',
c: 'flexweb',
},
});
const $ = cheerio.load(response.data);
const list = $('div.prices li a');
ctx.state.data = {
title,
link: url,
description: title,
item: list
.map((i, e) => {
const item = $(e).attr('href');
let reg = new RegExp('destination=(.*?)&', 'g');
const destination = reg.exec(item)[1];
reg = new RegExp('origin=(.*?)&', 'g');
const origin = reg.exec(item)[1];
reg = new RegExp('departureDate=(.*?)&', 'g');
const departureDate = reg.exec(item)[1];
reg = new RegExp('returnDate=(.*?)&', 'g');
const returnDate = reg.exec(item)[1];
const price = $(list[i])
.find('.price')
.text();
const title = `${origin} &#9992; ${destination} ${getMonthYear(departureDate)} for ${price}`;
const description = `<table><tbody><tr><th align="left" style="border: 1px solid black;">From</th><th align="left" style="border: 1px solid black;">To</th><th align="left" style="border: 1px solid black;">Price</th></tr><tr><td style="border: 1px solid black;">
${origin}</td><td style="border: 1px solid black;">${destination}</td><td style="border: 1px solid black;">${price}</td></tr></tbody></table>${formatDate(departureDate)} &#9992; ${formatDate(returnDate)}`;
return {
title,
description,
guid: item,
link: item,
};
})
.get(),
};
};
function formatDate(v) {
return new Intl.DateTimeFormat('en-gb', {
year: 'numeric',
weekday: 'short',
month: 'short',
day: 'numeric',
}).format(new Date(v));
}
function getMonthYear(v) {
const date = new Date(v);
return date.toLocaleString('en-gb', {
month: 'long',
year: 'numeric',
});
}