var express = require('express'), router = express.Router(), utils = require("../utils"), config = require("../config"); var isA = true; // 别人的后端c router.all('*', (req, res, next) => { isA = Boolean(req.query.isAndroid) || false res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Headers", "*"); res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS"); res.header("X-Powered-By", 'bmy') res.header("Content-Type", "application/json;charset=utf-8"); next(); }); /** * 1:获取首页推荐写真集列表 【页面完成】 * 接口地址:http://127.0.0.1:3000/api/json/index */ router.get('/index', async (req, res, next) => { let $ = await utils.get(config.BaseUrl); let result = { recommended: { title: '今日推荐', data: [] }, newest: { title: '最新收录', data: [] }, model: { title: '女神模特', res: [] } }; var inx = 0; $(".hezi ul li").each(function (i, el) { if (i < 8) { result.recommended.data.push({ id: parseInt($(this).find("a").attr("href").split("/a/")[1]), total: parseInt($(this).find(".shuliang").text()), total_page: Math.ceil(parseInt($(this).find(".shuliang").text()) / 5), source: clearText(`来源机构:${$(this).find("p").eq(0).find("a").text()}`), user: clearText($(this).find("p").eq(1).text()), tags: [], title: clearText($(this).find(".biaoti a").text()), preview: returnUrl($(this).find("a img").attr("src")), }); $(this).find("p").eq(2).find("a").each(function (index, ele) { result.recommended.data[i].tags.push({ title: $(this).text(), id: parseInt($(this).attr("href").split("/s/")[1]) }) }); } else { result.newest.data.push({ id: parseInt($(this).find("a").attr("href").split("/a/")[1]), total: parseInt($(this).find(".shuliang").text()), total_page: Math.ceil(parseInt($(this).find(".shuliang").text()) / 5), source: clearText(`来源机构:${$(this).find("p").eq(0).find("a").text()}`), user: clearText($(this).find("p").eq(1).text()), tags: [], title: $(this).find(".biaoti a").text(), preview: returnUrl($(this).find("a img").attr("src")), }) $(this).find("p").eq(2).find("a").each(function (index, ele) { result.newest.data[inx].tags.push({ title: $(this).text(), id: parseInt($(this).attr("href").split("/s/")[1]) }) }); inx += 1; } }); $(".hezi_t ul li").each(function () { result.model.res.push({ id: parseInt($(this).find("p a").attr("href").split("/t/")[1]), title: $(this).find("p a").text(), total: $(this).find(".shuliang").text(), preview: returnUrl($(this).find("a img").attr("src")), }) }) res.json({ status: 200, msg: '请求成功', result: result }) }); // ================ 查看写真详情 接口 ====================== /** * 2:进入写真集详情 * 接口地址:http://127.0.0.1:3000/api/json/info * 参数: * page 页数 * id 从首页带过来的 id参数 * 示例:http://127.0.0.1:3000/api/json/info?id=36351&page=1 * */ router.get('/info', async (req, res, next) => { let page = req.query.page; let id = req.query.id; let $ = await utils.get(config.InfoUrl(id, page)); let result = { title: '', // 写真标题 source: '', // 来源 total: '', // 图片总数 info: '', // 模特详情 current_page: '', // 当前页 total_page: '', // 总页数 data: [], // 图片数组 recommend: [], // 推荐写真 relevant: [], // 相关写真集 }; result.title = $(".tuji .weizhi h1").text().split(" / ")[0]; result.source = clearText(`拍摄机构:${$(".tuji p").eq(0).find("a").text()}`); if ($(".tuji p").eq(1).text().includes("图片数量")) { result.total = $(".tuji p").eq(1).text(); } else { result.total = $(".tuji p").eq(2).text(); } if ($(".tuji .shuoming").length == 0) { result.info = clearText(`${$(".tuji p").eq($(".tuji p").length - 1).text()}`); } else { result.info = clearText(`${$(".tuji p").eq($(".tuji p").length - 2).text()}`); } result.current_page = Number(page); result.total_page = Math.ceil(parseInt(result.total.split("图片数量: ")[1]) / 5); $(".content img").each(async function (i) { result.data.push({ title: $(this).attr("alt"), src: returnUrl($(this).attr("src")) }) }) $(".hezi").eq(0).find("ul li").each(function (i) { result.recommend.push({ id: parseInt($(this).find("a").attr("href").split("/a/")[1]), total: parseInt($(this).find(".shuliang").text()), total_page: Math.ceil(parseInt($(this).find(".shuliang").text()) / 5), source: clearText(`来源机构:${$(this).find("p").eq(0).find("a").text()}`), user: clearText($(this).find("p").eq(1).text()), tags: [], title: clearText($(this).find(".biaoti a").text()), preview: returnUrl($(this).find("a img").attr("src")), }); $(this).find("p").eq(2).find("a").each(function (index, ele) { result.recommend[i].tags.push({ title: $(this).text(), id: parseInt($(this).attr("href").split("/s/")[1]) }) }) }) $(".hezi").eq(1).find("ul li").each(function (i) { result.relevant.push({ id: parseInt($(this).find("a").attr("href").split("/a/")[1]), total: parseInt($(this).find(".shuliang").text()), total_page: Math.ceil(parseInt($(this).find(".shuliang").text()) / 5), source: clearText(`来源机构:${$(this).find("p").eq(0).find("a").text()}`), user: clearText($(this).find("p").eq(1).text()), tags: [], title: $(this).find(".biaoti a").text(), preview: returnUrl($(this).find("a img").attr("src")), }); $(this).find("p").eq(2).find("a").each(function (index, ele) { result.relevant[i].tags.push({ title: $(this).text(), id: parseInt($(this).attr("href").split("/s/")[1]) }) }) }); res.json({ status: 200, msg: '请求成功', result: result }) }) // ================ 写真机构 接口 ====================== /** * 3:获取各大国内外写真机构列表 【页面完成】 * 接口地址:http://127.0.0.1:3000/api/json/mechanism */ router.get('/mechanism', async (req, res, next) => { let $ = await utils.get(config.jigou()); var result = [] $(".jigou li").each(function () { result.push({ id: parseInt($(this).find("a").attr("href").split("/x/")[1]), title: $(this).find("a").text(), quantity: $(this).find("span").text() }) }); res.json({ status: 200, msg: '请求成功', result: result }) }) /** * 4:获取该机构下写真套图列表 【页面完成】 * 接口地址:http://127.0.0.1:3000/api/json/mechanismList * 参数: * page 页数 注意page默认从 0 开始 * id 接口3的id * 示例:http://127.0.0.1:3000/api/json/mechanismList?id=82&page=0 */ router.get('/mechanismList', async (req, res, next) => { var id = req.query.id; var page = req.query.page; let $ = await utils.get(config.jigouList(id, page)); var TotalList = $(".shoulushuliang span").text(); var calculation = TotalList / 40; var result = { group: TotalList, // 该分类下有多少套写真图 current_page: Number(page), // 当前页数 // 该分类有多少页 total_page: Number.isInteger(calculation) ? calculation - 1 : parseInt(calculation), // 当页的数据 data: [] }; $(".hezi ul li").each(function (i, el) { result.data.push({ id: parseInt($(this).find("a").attr("href").split("/a/")[1]), total: parseInt($(this).find(".shuliang").text()), total_page: Math.ceil(parseInt($(this).find(".shuliang").text()) / 5), source: '', user: clearText($(this).find("p").eq(0).text()), tags: [], title: $(this).find(".biaoti a").text(), preview: returnUrl($(this).find("a img").attr("src")), }); $(this).find("p").eq(1).find("a").each(function (index, ele) { result.data[i].tags.push({ title: $(this).text(), id: parseInt($(this).attr("href").split("/s/")[1]) }) }) }); res.json({ status: 200, msg: '请求成功', result: result }) }) // ================ 推荐分类 接口 ====================== /** * 5:获取写真分类列表 【页面完成】 * 接口地址:http://127.0.0.1:3000/api/json/class */ router.get('/class', async (req, res, next) => { let $ = await utils.get(config.BaseUrl); var result = { principal: [], additional: [ {id: 40,title:'萝莉控',page: 0}, {id: 104,title:'白丝诱惑',page: 0}, {id: 189,title:'双马尾',page: 0}, {id: 20,title:'护士制服',page: 0}, {id: 207,title:'丝足诱惑',page: 0}, {id: 27,title:'性感女仆装',page: 0}, {id: 50,title:'湿身诱惑',page: 0}, {id: 62,title:'御姐控',page: 0}, {id: 68,title:'古典气质',page: 0}, {id: 69,title:'旗袍美女',page: 0}, {id: 70,title:'人体艺术',page: 0}, {id: 43,title:'福利图片',page: 0}, {id: 75,title:'性感浴室',page: 0}, {id: 78,title:'性感网袜',page: 0}, {id: 81,title:'阳光少女',page: 0}, {id: 82,title:'居家私房',page: 0}, {id: 89,title:'巨乳波霸',page: 0}, {id: 110,title:'性感豹纹',page: 0}, {id: 100,title:'日本女明星',page: 0}, {id: 112,title:'空姐制服',page: 0}, {id: 114,title:'SM镣铐',page: 0}, {id: 121,title:'粉嫩少女',page: 0}, {id: 122,title:'教师制服',page: 0}, {id: 123,title:'美女警察',page: 0}, {id: 145,title:'床上美女',page: 0}, {id: 147,title:'OL制服',page: 0}, {id: 130,title:'姐妹花',page: 0}, {id: 131,title:'性感健身',page: 0}, {id: 125,title:'美厨娘',page: 0}, {id: 128,title:'情趣皮衣',page: 0}, {id: 134,title:'透视诱惑',page: 0}, {id: 146,title:'美女秘书',page: 0}, {id: 157,title:'西装美女',page: 0}, {id: 184,title:'黑长直',page: 0}, {id: 190,title:'老照片美女',page: 0}, {id: 191,title:'肉感美女',page: 0}, {id: 192,title:'学生装美女',page: 0}, {id: 194,title:'写真杂志',page: 0}, {id: 195,title:'欧美巨乳',page: 0}, {id: 196,title:'金发美女',page: 0}, {id: 197,title:'欧美熟妇',page: 0}, {id: 199,title:'欧美制服',page: 0}, {id: 201,title:'黑人美女',page: 0}, {id: 202,title:'巨乳肥臀',page: 0}, {id: 203,title:'长靴美女',page: 0}, {id: 204,title:'丝袜美臀',page: 0}, {id: 206,title:'美臀少妇',page: 0}, {id: 228,title:'美女制服诱惑',page: 0}, {id: 211,title:'不知火舞COS',page: 0}, {id: 212,title:'性感女郎',page: 0}, {id: 213,title:'丝袜女郎',page: 0}, {id: 214,title:'轻熟女写真集',page: 0}, {id: 215,title:'比基尼少女',page: 0}, {id: 216,title:'日本比基尼',page: 0}, {id: 217,title:'中国比基尼',page: 0}, {id: 219,title:'风骚诱惑',page: 0}, {id: 220,title:'风骚少妇',page: 0}, {id: 221,title:'丰满少妇',page: 0}, {id: 222,title:'丝袜少妇',page: 0}, {id: 224,title:'黑丝美腿',page: 0}, {id: 225,title:'黑丝制服',page: 0}, {id: 226,title:'街拍黑丝',page: 0}, {id: 227,title:'日本巨乳AV女优',page: 0}, {id: 229,title:'蕾丝诱惑',page: 0}, {id: 231,title:'半裸尤物',page: 0}, {id: 232,title:'勾魂尤物',page: 0}, {id: 233,title:'丝袜肥臀',page: 0}, {id: 235,title:'街拍美腿',page: 0}, {id: 236,title:'巨乳萝莉',page: 0}, {id: 237,title:'丝袜制服',page: 0}, {id: 238,title:'街拍短裙',page: 0}, {id: 239,title:'丝袜短裙',page: 0}, {id: 240,title:'丝袜人体艺术',page: 0}, {id: 242,title:'性感丰满',page: 0}, {id: 243,title:'街拍丝袜',page: 0}, {id: 244,title:'超短迷你裙',page: 0}, {id: 245,title:'开背毛衣',page: 0}, {id: 247,title:'性感香车',page: 0}, {id: 248,title:'吊带美女',page: 0}, {id: 249,title:'极品美丝',page: 0}, {id: 250,title:'眼镜娘',page: 0}, {id: 251,title:'极品女友',page: 0}, {id: 53,title:'大胸嫩模',page: 0}, {id: 73,title:'情趣内衣',page: 0}, {id: 254,title:'白领丽人',page: 0}, {id: 255,title:'美女故事',page: 0}, {id: 256,title:'极品抹胸',page: 0}, {id: 257,title:'情趣制服',page: 0}, {id: 258,title:'肉丝高跟',page: 0}, {id: 259,title:'黑丝袜诱惑',page: 0}, {id: 113,title:'婚纱美女',page: 0}, {id: 108,title:'丽柜美束系列',page: 0}, ] }; $("#tag_ul li a").each(function () { result.principal.push({ id: parseInt($(this).attr("href").split("/s/")[1]), title: $(this).text(), page: 0 }) }) result.principal.unshift({ id: 36, title: 'COSPLAY',page: 0 }) result.principal.unshift({ id: 10, title: '办公室',page: 0 }) result.principal.unshift({ id: 124, title: 'JK制服',page: 0 }) result.principal.unshift({ id: 46, title: '翘臀',page: 0 }) result.principal.unshift({ id: 12, title: '长筒袜',page: 0 }) result.principal.unshift({ id: 65, title: '街拍',page: 0 }) result.principal.unshift({ id: 67, title: '捆绑绳艺',page: 0 }) result.principal.unshift({ id: 253, title: '黑丝萝莉',page: 0 }) result.principal.unshift({ id: 127, title: '紧身裤',page: 0 }) result.principal.unshift({ id: 252, title: '白丝萝莉',page: 0 }) result.principal.unshift({ id: 64, title: '丁字裤',page: 0 }) result.principal.unshift({ id: 18, title: '热裤',page: 0 }) result.principal.unshift({ id: 48, title: '猫女郎',page: 0 }) // 【必看】模特列表:https://www.tujigu.com/s/85/ // 网红美女、网红模特写真 https://www.tujigu.com/s/116/ // 日本AV女优写真 https://www.tujigu.com/s/159/ // B罩杯美女 https://www.tujigu.com/s/170/ 171 172 173 174 175 176 177 178 179 res.json({ status: 200, msg: '请求成功', result: result }) }) /** * 6:进入分类的详情列表,获取该分类下有多少套图,用在接口5上 【页面完成】 * 接口地址:http://127.0.0.1:3000/api/json/classList * 参数: * page 页数 注意page默认从 0 开始 * id 代入的接口4 id 或者 接口1 的tags id * 示例:http://127.0.0.1:3000/api/json/classList?id=124&page=0 */ router.get('/classList', async (req, res, next) => { var id = req.query.id; var page = req.query.page; let $ = await utils.get(config.ClassList(id, page)); var TotalList = $(".shoulushuliang span").text(); var calculation = TotalList / 40; var result = { group: TotalList, // 该分类下有多少套写真图 current_page: Number(page), // 当前页数 // 该分类有多少页 total_page: Number.isInteger(calculation) ? calculation - 1 : parseInt(calculation), // 当页的数据 data: [] }; $(".hezi ul li").each(function (i, el) { result.data.push({ id: parseInt($(this).find("a").attr("href").split("/a/")[1]), total: parseInt($(this).find(".shuliang").text()), total_page: Math.ceil(parseInt($(this).find(".shuliang").text()) / 5), source: clearText(`来源机构:${$(this).find("p").eq(0).find("a").text()}`), user: clearText($(this).find("p").eq(1).text()), tags: [], title: $(this).find(".biaoti a").text(), preview: returnUrl($(this).find("a img").attr("src")), }); $(this).find("p").eq(2).find("a").each(function (index, ele) { result.data[i].tags.push({ title: $(this).text(), id: parseInt($(this).attr("href").split("/s/")[1]) }) }) }); res.json({ status: 200, msg: '请求成功', result: result }) }) // ================ 模特相关 接口 ====================== /** * 7:获取所有模特 【页面完成】 * 接口地址:http://127.0.0.1:3000/api/json/allModel * 示例:http://127.0.0.1:3000/api/json/allModel */ router.get('/allModel', async (req, res, next) => { let $ = await utils.get(config.AllModel()); var result = { hot_models: [], newest: [] }; $(".hezi_t").eq(0).find("ul li").each(function () { result.hot_models.push({ id: parseInt($(this).find("p a").attr("href").split("/t/")[1]), title: $(this).find("p a").text(), total: $(this).find(".shuliang").text(), preview: returnUrl($(this).find("a img").attr("src")), }) }) $(".hezi_t").eq(1).find("ul li").each(function () { result.newest.push({ id: parseInt($(this).find("p a").attr("href").split("/t/")[1]), title: $(this).find("p a").text(), total: $(this).find(".shuliang").text(), preview: returnUrl($(this).find("a img").attr("src")), }) }) res.json({ status: 200, msg: '请求成功', result: result }) }); /** * 8:进入模特的个人套图页,可用于 接口1 的 model 【页面完成】 * 接口地址:http://127.0.0.1:3000/api/json/modelList * 参数: * page 页数 注意page默认从 0 开始 * id 从首页带过来的 id参数 * 示例:http://127.0.0.1:3000/api/json/modelList?id=3265&page=0 */ router.get('/modelList', async (req, res, next) => { var id = req.query.id; var page = req.query.page; let $ = await utils.get(config.ModelList(id, page)); var total = $(".shoulushuliang span").text(); var result = { current_page: parseInt(page), total_page: total <= 40 ? 99999 : Number.isInteger(total / 40) ? total / 40 - 1 : parseInt(total / 40), model_info: { portrait: returnUrl($(".renwu .left img").attr("src")), name: clearText($(".renwu .left img").attr("alt")), explain: clearText($(".renwu .shuoming").text().split("模特标签: ")[0]), total: total }, data: [], similar: [] } $(".hezi ul li").each(function (i, el) { result.data.push({ id: parseInt($(this).find("a").attr("href").split("/a/")[1]), total: parseInt($(this).find(".shuliang").text()), total_page: Math.ceil(parseInt($(this).find(".shuliang").text()) / 5), source: clearText(`来源机构:${$(this).find("p").eq(0).find("a").text()}`), tags: [], user: '', title: $(this).find(".biaoti a").text(), preview: returnUrl($(this).find("a img").attr("src")), }); $(this).find("p").eq(1).find("a").each(function (index, ele) { result.data[i].tags.push({ title: $(this).text(), id: parseInt($(this).attr("href").split("/s/")[1]) }) }) }); $(".hezi_t ul li").each(function () { result.similar.push({ id: parseInt($(this).find("p a").attr("href").split("/t/")[1]), title: $(this).find("p a").text(), total: $(this).find(".shuliang").text(), preview: returnUrl($(this).find("a img").attr("src")), }) }) res.json({ status: 200, msg: '请求成功', result: result }) }) // ================ 搜索 接口 ====================== /** * 9:根据关键词搜索写真接口 * 接口地址:http://127.0.0.1:3000/api/json/search * 参数: * keyword 搜索关键词 * 示例:http://127.0.0.1:3000/api/json/search?keyword=女神 */ router.get('/search', async (req, res, next) => { var keyword = req.query.keyword; let $ = await utils.get(config.Search(keyword)); var result = []; $(".hezi ul li").each(function () { result.push({ id: parseInt($(this).find("a").attr("href").split("/a/")[1]), title: $(this).find(".biaoti a").text(), preview: returnUrl($(this).find("a img").attr("src")), }) }) res.json({ status: 200, msg: '请求成功', result: result }) }) /** * 10: 破解有防盗链的图片地址 * 接口地址:http://127.0.0.1:3000/api/json/url * 参数: * url 图片地址 * 示例:http://127.0.0.1:3000/api/json/url?url=https://lns.hywly.com/a/1/24510/0.jpg */ router.get('/url', async (req, res, next) => { const http = require('https'); const URL = require('url'); var url = URL.parse(req.query.url); var option={ hostname: url.hostname, path: url.path, rejectUnauthorized: false, headers:{ "Referer":"https://www.tujigu.com/" } }; http.get(option, function (response) { var chunks = []; response.on('data', function (chunk) { chunks.push(chunk); }).on('end', function () { // 保存图片ArrayBuffer 数据 var buffer = Buffer.concat(chunks); // 设置前端请求头 res.set(response.headers) // 两次二进制转换 res.end(buffer.toString("binary"), 'binary') }); }); }); function returnUrl(url) { isA = true; return isA ? url : "http://47.114.153.249:3000/api/json/url?url="+url } function clearText(text) { return text.replace(/\ +/g,"").replace(/[\r\n]/g,"");; } module.exports = router;