const axios = require('axios');
class DeviantArt {
constructor() {
this.inst = axios.create({
baseURL: 'https://www.deviantart.com',
headers: {
origin: 'https://www.deviantart.com',
referer: 'https://www.deviantart.com/',
'user-agent': 'Mozilla/5.0 (Linux; Android 15; SM-F958 Build/AP3A.240905.015) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.86 Mobile Safari/537.36'
}
});
}
getCsrf = async function () {
try {
const { data: html, headers } = await this.inst.get('/');
const csrf = html.match(/window\.__CSRF_TOKEN__\s*=\s*'([^']*)'/)?.[1];
if (!csrf) throw new Error('Failed to get csrf token.');
const cookies = headers['set-cookie']?.join('; ') || '';
this.inst.defaults.headers.common['cookie'] = cookies;
return csrf;
} catch (error) {
throw new Error(error.message);
}
}
search = async function ({ query, cursor } = {}) {
try {
if (!query) throw new Error('Query is required.');
const csrf = await this.getCsrf();
const { data } = await this.inst.get('/_puppy/dabrowse/search/all', {
params: {
q: query,
da_minor_version: 20230710,
csrf_token: csrf,
...(cursor && { cursor: cursor })
}
});
return data;
} catch (error) {
throw new Error(error.message);
}
}
detail = async function (url) {
try {
const match = url.match(/https?:\/\/(?:www\.)?deviantart\.com\/([^\/]+)\/(art|journal)\/[^\/]+-(\d+)/);
if (!match) throw new Error('Invalid url.');
const csrf = await this.getCsrf();
const { data } = await this.inst.get('/_puppy/dadeviation/init', {
params: {
deviationid: match[3],
username: match[1],
type: match[2],
include_session: false,
csrf_token: csrf,
expand: 'deviation.related',
preload: true,
da_minor_version: 20230710
}
});
return data;
} catch (error) {
throw new Error(error.message);
}
}
}
const d = new DeviantArt();
d.search({ query: 'hutao' }).then(console.log);