red-note-api
Version:
Parse the Xiaohongshu API
234 lines (233 loc) • 10.1 kB
JavaScript
"use strict";
// noinspection JSStringConcatenationToES6Template,ES6ConvertRequireIntoImport,ExceptionCaughtLocallyJS,JSUnusedGlobalSymbols,JSUnusedLocalSymbols
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const axios_1 = __importDefault(require("axios"));
const query_string_1 = __importDefault(require("query-string"));
const get_xs = require('./jsvmp/xhs.js');
const { getXCommon, getSearchId, getRequestId } = require('./help.js');
const { ErrorEnum, DataFetchError, IPBlockError, SignError, NeedVerifyError } = require('./exception.js');
class RedNoteClient {
constructor(cookie, userAgent, timeout) {
this._host = 'https://edith.xiaohongshu.com';
this._creatorHost = 'https://creator.xiaohongshu.com';
this._customerHost = 'https://customer.xiaohongshu.com';
this.timeout = timeout;
this.userAgent = userAgent;
this.axiosInstance = axios_1.default.create({
timeout: this.timeout,
headers: {
'user-agent': this.userAgent,
'Content-Type': 'application/json'
}
});
if (cookie) {
this.cookie = cookie;
}
}
set cookie(cookie) {
this.axiosInstance.defaults.headers.Cookie = cookie;
}
get cookie() {
return this.axiosInstance.defaults.headers.Cookie;
}
get cookieDict() {
const cookieStr = this.cookie;
return cookieStr ? query_string_1.default.parse(cookieStr.replace(/; /g, '&')) : {};
}
_preHeaders(url, data = null) {
let a1 = this.cookieDict.a1;
let b1 = '';
let x_s_result = get_xs(url, data, this.cookie);
const X_S = x_s_result['X-s'];
const X_t = x_s_result['X-t'].toString();
const X_S_COMMON = getXCommon(a1, b1, X_S, X_t);
this.axiosInstance.defaults.headers['X-s'] = X_S;
this.axiosInstance.defaults.headers['X-t'] = X_t;
this.axiosInstance.defaults.headers['X-s-common'] = X_S_COMMON;
}
request(method_1, url_1) {
return __awaiter(this, arguments, void 0, function* (method, url, config = {}) {
try {
const response = yield this.axiosInstance(Object.assign({ method, url }, config));
if (!response.data)
return response;
// console.log('response', response)
if (response.status === 471 || response.status === 461) {
const verifyType = response.headers['verifytype'];
const verifyUuid = response.headers['verifyuuid'];
throw new NeedVerifyError(`出现验证码,请求失败,Verifytype: ${verifyType},Verifyuuid: ${verifyUuid}`, response, verifyType, verifyUuid);
}
const data = response.data;
if (data.success) {
return data.data || data.success;
}
else if (data.code === ErrorEnum.IP_BLOCK.code) {
throw new IPBlockError(ErrorEnum.IP_BLOCK.msg, response);
}
else if (data.code === ErrorEnum.SIGN_FAULT.code) {
throw new SignError(ErrorEnum.SIGN_FAULT.msg, response);
}
else {
throw new DataFetchError(data, response);
}
}
catch (error) {
if (error.response && (error.response.status === 471 || error.response.status) === 461) {
// Handle verification error
const verifyType = error.response.headers['verifytype'];
const verifyUuid = error.response.headers['verifyuuid'];
throw new NeedVerifyError(`出现验证码,请求失败,Verifytype: ${verifyType},Verifyuuid: ${verifyUuid}`, error.response, verifyType, verifyUuid);
}
throw error;
}
});
}
get(uri_1) {
return __awaiter(this, arguments, void 0, function* (uri, params = null, isCreator = false, isCustomer = false, config = {}) {
let finalUri = uri;
if (params) {
finalUri = `${uri}?${query_string_1.default.stringify(params)}`;
}
this._preHeaders(finalUri, null);
let endpoint = this._host;
if (isCustomer) {
endpoint = this._customerHost;
}
else if (isCreator) {
endpoint = this._creatorHost;
}
return this.request('GET', `${endpoint}${finalUri}`, config);
});
}
post(uri_1) {
return __awaiter(this, arguments, void 0, function* (uri, data = null, isCreator = false, isCustomer = false, config = {}) {
// let jsonStr = data ? JSON.stringify(data).replace(/[\u007F-\uFFFF]/g, function(chr) {
// return "\\u" + ("0000" + chr.charCodeAt(0).toString(16)).substr(-4);
// }) : null;
this._preHeaders(uri, data);
let endpoint = this._host;
if (isCustomer) {
endpoint = this._customerHost;
}
else if (isCreator) {
endpoint = this._creatorHost;
}
if (data) {
return this.request('POST', `${endpoint}${uri}`, Object.assign(Object.assign({}, config), { data: data, headers: Object.assign(Object.assign({}, config.headers), { 'Content-Type': 'application/json' }) }));
}
return this.request('POST', `${endpoint}${uri}`, Object.assign(Object.assign({}, config), { data }));
});
}
getNoteById(noteId_1) {
return __awaiter(this, arguments, void 0, function* (noteId, image_scenes = ['CRD_WM_WEBP']) {
const data = {
source_note_id: noteId,
image_scenes: image_scenes
};
const uri = '/api/sns/web/v1/feed';
try {
const res = yield this.post(uri, data);
return res.items[0].note_card;
}
catch (error) {
console.error('Error fetching note:', error);
throw error;
}
});
}
getSelfInfo() {
return __awaiter(this, void 0, void 0, function* () {
const uri = '/api/sns/web/v2/user/me';
return this.get(uri);
});
}
searchUser(keyword_1) {
return __awaiter(this, arguments, void 0, function* (keyword, page = 1, page_size = 20) {
const body = {
search_user_request: {
biz_type: 'web_search_user',
keyword: keyword,
page: page,
page_size: page_size,
request_id: getRequestId(),
search_id: getSearchId()
}
};
const uri = '/api/sns/web/v1/search/usersearch';
return this.post(uri, body);
});
}
searchNotes(keyword_1) {
return __awaiter(this, arguments, void 0, function* (keyword, page = 1, page_size = 20, sort = 'general', note_type = 0, // 0 = All, 1 = Video, 2 = Image
ext_flags = [], image_formats = ['jpg', 'webp', 'avif']) {
const body = {
keyword: keyword,
page: page,
page_size: page_size,
search_id: getSearchId(),
sort: sort,
note_type: note_type,
ext_flags: ext_flags,
image_formats: image_formats
};
const uri = '/api/sns/web/v1/search/notes';
return this.post(uri, body);
});
}
getUserInfo(userId) {
return __awaiter(this, void 0, void 0, function* () {
const uri = '/api/sns/web/v1/user/otherinfo';
const params = {
target_user_id: userId
};
return this.get(uri, params);
});
}
getNoteListByUserId() {
return __awaiter(this, arguments, void 0, function* (num = 30, cursor = '', user_id, image_scenes = 'FD_WM_WEBP') {
const uri = '/api/sns/web/v1/user_posted';
const data = {
//
num: num,
cursor: cursor,
user_id: user_id,
image_scenes: image_scenes
};
return this.get(uri, data);
});
}
postComment(note_id_1, content_1, target_comment_id_1) {
return __awaiter(this, arguments, void 0, function* (note_id, content, target_comment_id, at_users = []) {
const uri = '/api/sns/web/v1/comment/post';
const body = {
note_id: note_id,
content: content,
target_comment_id: target_comment_id,
at_users: at_users
};
return this.post(uri, body);
});
}
deleteComment(note_id, comment_id) {
return __awaiter(this, void 0, void 0, function* () {
const uri = '/api/sns/web/v1/comment/delete';
return this.post(uri, {
note_id: note_id,
comment_id: comment_id
});
});
}
}
exports.default = RedNoteClient;