Fix: Bypassing Cloudflare's TLS fingerprint detection for Node.js using curl.

This commit is contained in:
Unknow committed 2026-03-20 21:09:49 +08:00
1 parent df68291483
commit 51c9ccceef
2 files changed
+23 -62

No files matched your search

+22 -61
View File
@@ -1,61 +1,44 @@
import axios from 'axios';
import { execSync } from 'child_process';
import * as cheerio from 'cheerio';
import { getCache, setCache } from './cache.js';
const BASE_URL = 'https://javdb.com';
// 把 _jdb_session 的值解码
const SESSION = decodeURIComponent('wJkH2678EN3cZzzL2Pqbyr158quff0CaGzuh5hRxUXXADcKOQm1zKdOnlwow3wDfL5AX2NeKne52BgUZT6JpBGp5prKgUmKyBReopEABv30rItmWnxowjJ04Mki%2BO0jQ3OO%2F4F2BYE7TTZ8GlgpA3kuesTAsX8bAcL0HqWF4LDRdMeo9JYqzDn%2FoPAUFxnmwXBieXtMXqCP8JnudI2vQ44jtIhFRvSrzf832gRMi7STwMG7K8O9%2BH3AoJfMKbuBomnLMFuBNBbPbB3SShbi3SBja8bX8nudBILUX0ZiJtD%2FEOl%2BN3r6dVPw5--do%2Bi7mvLi5xyZ0HZ--gZT%2Fl7%2BX9Vr3GjRNK7FXOw%3D%3D');
const HEADERS = {
'User-Agent':
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) ' +
'AppleWebKit/537.36 (KHTML, like Gecko) ' +
'Chrome/123.0.0.0 Safari/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
'Accept-Encoding': 'gzip, deflate, br',
'Connection': 'keep-alive',
'Upgrade-Insecure-Requests': '1',
'Sec-Fetch-Dest': 'document',
'Sec-Fetch-Mode': 'navigate',
'Sec-Fetch-Site': 'none',
'Sec-Fetch-User': '?1',
'Cache-Control': 'max-age=0',
Cookie: `list_mode=h; theme=auto; locale=zh; over18=1; _jdb_session=${SESSION}`, // over18=1 跳过成人内容确认页
};
const COOKIE = `list_mode=h; theme=auto; locale=zh; over18=1; _jdb_session=${SESSION}`;
const BASE_URL = 'https://javdb.com';
async function fetchHtml(url) {
const res = await axios.get(url, {
headers: HEADERS,
timeout: 15000,
maxRedirects: 5,
decompress: true,
});
return res.data;
function fetchHtml(url) {
const result = execSync(
`curl -sL "${url}" \
-H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36" \
-H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8" \
-H "Accept-Language: zh-CN,zh;q=0.9,en;q=0.8" \
-H "Cookie: ${COOKIE}"`,
{ timeout: 15000, maxBuffer: 1024 * 1024 * 10 }
);
return result.toString();
}
export async function search(id) {
// 第一步:先查缓存
const cached = getCache(id);
if (cached) return cached;
// 缓存没有,走网络请求,搜索番号,拿到详情页链接
const searchUrl = `${BASE_URL}/search?q=${encodeURIComponent(id)}&f=all`;
const searchHtml = await fetchHtml(searchUrl);
const searchHtml = fetchHtml(searchUrl);
const $ = cheerio.load(searchHtml);
// 找第一个匹配的结果卡片
const firstResult = $('.movie-list .item a').first();
if (!firstResult.length) return null;
const detailPath = firstResult.attr('href');
if (!detailPath) return null;
// 第二步:抓取详情页
const detailUrl = `${BASE_URL}${detailPath}`;
const detailHtml = await fetchHtml(detailUrl);
return parseDetail(detailHtml, id);
const detailHtml = fetchHtml(detailUrl);
const result = parseDetail(detailHtml, id);
setCache(id, result);
return result;
}
function parseDetail(html, queryId) {
@@ -75,20 +58,13 @@ function parseDetail(html, queryId) {
tags: [],
coverUrl: '',
score: '',
detailUrl: '',
};
// 标题
result.title = $('h2.title strong.current-title').text().trim() ||
$('h2.title').text().trim();
// 封面图
result.coverUrl = $('.video-cover img').attr('src') || '';
// 评分
result.score = $('.score .value').first().text().trim();
// 遍历 panel info 的每一行
$('.movie-panel-info .panel-block').each((_, el) => {
const label = $(el).find('strong').text().trim().replace(':', '');
const valueEl = $(el).find('.value');
@@ -97,53 +73,38 @@ function parseDetail(html, queryId) {
case /日期|發行|发行/.test(label):
result.releaseDate = valueEl.text().trim();
break;
case /時長|时长|分鐘|分钟/.test(label):
result.duration = valueEl.text().trim();
break;
case /導演|导演/.test(label):
result.director = valueEl.text().trim();
break;
case /片商|制作|製作/.test(label):
result.studio = valueEl.text().trim();
break;
case /發行商|发行商/.test(label):
result.label = valueEl.text().trim();
break;
case /系列/.test(label):
result.series = valueEl.text().trim();
break;
case /類別|类别|genre/i.test(label):
valueEl.find('a').each((_, a) => {
result.tags.push($(a).text().trim());
});
valueEl.find('a').each((_, a) => result.tags.push($(a).text().trim()));
break;
case /演員|演员|女優|女优/.test(label): {
case /演員|演员|女優|女优/.test(label):
valueEl.find('a').each((_, a) => {
const name = $(a).text().trim();
if (name) result.actresses.push(name);
});
break;
}
case /男優|男优/.test(label): {
case /男優|男优/.test(label):
valueEl.find('a').each((_, a) => {
const name = $(a).text().trim();
if (name) result.actors.push(name);
});
break;
}
}
});
// 写入缓存
setCache(id, result);
return result;
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "javinfo",
"version": "1.0.3",
"version": "1.0.4",
"description": "AV番号命令行查询工具",
"main": "./index.js",
"type": "module",