无需服务器自动爬取图床图片到网盘中

开始前准备:

huggingface账号:

https://huggingface.co/

**其他容器平台也可运行**
网盘账号:
https://infini-cloud.net/en/

`Dockerfile`

```
FROM node:14

WORKDIR /app

COPY package.json .
RUN npm install

COPY . .

EXPOSE 8080

CMD [“node”, “index.js”]
```

`README.md` 最后加

``` app_port: 8080 ```

`index.js`

``` const http = require('http'); const fetch = require('node-fetch'); const cron = require('node-cron'); const { createClient } = require('webdav'); const axios = require('axios'); const crypto = require('crypto');

const IMAGE_API_URL = ‘https://tuapi.eees.cc/api.php?category={dongman,fengjing,biying,meinv}&type=302’;
const PORT = process.env.PORT || 8080;

// WebDAV configuration from environment variables
const WEBDAV_BASE_URL = process.env.WEBDAV_URL;
const WEBDAV_USERNAME = process.env.WEBDAV_USERNAME;
const WEBDAV_PASSWORD = process.env.WEBDAV_PASSWORD;

if (!WEBDAV_BASE_URL || !WEBDAV_USERNAME || !WEBDAV_PASSWORD) {
console.error(‘WebDAV configuration is missing. Please set WEBDAV_URL, WEBDAV_USERNAME, and WEBDAV_PASSWORD environment variables.’);
process.exit(1);
}

const WEBDAV_API_URL = WEBDAV_BASE_URL;

const webdavClient = createClient(WEBDAV_API_URL, {
username: WEBDAV_USERNAME,
password: WEBDAV_PASSWORD,
headers: {
‘User-Agent’: ‘Node.js WebDAV Client’
},
maxBodyLength: Infinity,
maxContentLength: Infinity
});

let uploadedImages = new Set();

async function getRandomImageUrl() {
const timestamp = Date.now();
const url = ${IMAGE_API_URL}&t=${timestamp};
try {
const response = await fetch(url, { redirect: ‘manual’ });
return response.headers.get(‘location’);
} catch (error) {
console.error(‘Error fetching random image URL:’, error);
return null;
}
}

async function checkDirectoryPermissions(dirPath) {
try {
console.log(Checking permissions for directory: ${dirPath});
const exists = await webdavClient.exists(dirPath);
if (!exists) {
console.log(Directory ${dirPath} does not exist. Attempting to create...);
await webdavClient.createDirectory(dirPath);
console.log(Directory ${dirPath} created successfully.);
} else {
console.log(Directory ${dirPath} already exists.);
}

// Try to create a test file
const testFilePath = `${dirPath}test_file_${Date.now()}.txt`;
await webdavClient.putFileContents(testFilePath, 'Test content');
console.log(`Test file created successfully at ${testFilePath}`);

// Delete the test file
await webdavClient.deleteFile(testFilePath);
console.log(`Test file deleted successfully.`);

return true;

} catch (error) {
console.error(Error checking directory permissions: ${error.message});
return false;
}
}

async function fileExistsInWebDAV(filePath) {
try {
return await webdavClient.exists(filePath);
} catch (error) {
console.error(Error checking file existence in WebDAV: ${error.message});
return false;
}
}

async function downloadAndUploadImage(imageUrl) {
try {
console.log(‘Downloading image from:’, imageUrl);
const response = await axios.get(imageUrl, { responseType: ‘arraybuffer’ });
const buffer = Buffer.from(response.data, ‘binary’);

// Generate a unique filename
const hash = crypto.createHash('md5').update(imageUrl).digest('hex');
const filename = `image_${hash}.jpg`;

// Ensure the directory exists and check permissions
const dirPath = '/images/';
const hasPermission = await checkDirectoryPermissions(dirPath);
if (!hasPermission) {
  throw new Error('No write permission for the directory');
}

// Check if file already exists in WebDAV
const fullPath = `${dirPath}${filename}`;
const fileExists = await fileExistsInWebDAV(fullPath);

if (fileExists) {
  console.log('Duplicate image detected:', fullPath);
  console.log('Skipping this update.');
  return null;
}

// Upload to WebDAV
console.log('Uploading file to:', fullPath);
await webdavClient.putFileContents(fullPath, buffer, { overwrite: true });

console.log('Successfully uploaded:', filename);
return `${WEBDAV_API_URL}${fullPath}`;

} catch (error) {
console.error(‘Error in downloadAndUploadImage:’, error);
return null;
}
}

async function updateImages() {
try {
const newImageUrl = await getRandomImageUrl();
if (!newImageUrl) {
console.log(‘Failed to get a valid image URL. Skipping this update.’);
return;
}

const uploadedUrl = await downloadAndUploadImage(newImageUrl);
if (uploadedUrl) {
  uploadedImages.add(uploadedUrl);
  console.log('New image uploaded:', uploadedUrl);
}

} catch (error) {
console.error(‘Error updating images:’, error);
}
}

function generateHtml() {
const imagesList = Array.from(uploadedImages).reverse();
return <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>随机图片链接</title> <style> body { font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; } h1 { color: #333; text-align: center; } ul { list-style-type: none; padding: 0; } li { margin-bottom: 10px; } a { color: #0066cc; text-decoration: none; word-break: break-all; } a:hover { text-decoration: underline; } </style> </head> <body> <h1>随机图片链接</h1> <p>当前共有 ${imagesList.length} 个链接</p> <ul> ${imagesList.map(url =>
<li><a href=“${url}” target=“_blank”>${url}</a></li>
).join('')} &lt;/ul&gt; &lt;/body&gt; &lt;/html&gt; ;
}

const server = http.createServer((req, res) => {
if (req.url === ‘/’) {
res.writeHead(200, { ‘Content-Type’: ‘text/html; charset=utf-8’ });
res.end(generateHtml());
} else {
res.writeHead(404);
res.end(‘Not Found’);
}
});

async function checkWebDAVConnection() {
try {
console.log(‘Checking WebDAV connection…’);
console.log(‘WebDAV API URL:’, WEBDAV_API_URL);

// Try to get directory contents
console.log('Trying to get root directory contents...');
const directoryContents = await webdavClient.getDirectoryContents('/');
console.log('Root directory contents:', directoryContents);

console.log('WebDAV connection successful.');

} catch (error) {
console.error(‘Error connecting to WebDAV server:’, error);
throw error;
}
}

// 主程序部分
checkWebDAVConnection()
.then(() => {
server.listen(PORT, () => {
console.log(Server running on port ${PORT});
});

// Initial update
updateImages();

// Update images every 10 seconds
setInterval(updateImages, 10000);

})
.catch(error => {
console.error(‘Failed to start server due to WebDAV connection error:’, error);
process.exit(1);
});
```

爬取的网站地址为:
https://tuapi.eees.cc/
类似的API接口的网站应该都是通用的,自己替换看行不行

`package.json`

</s><i> </i>{ "name": "random-image-links", "version": "1.0.0", "description": "Random image link generator and uploader", "main": "index.js", "dependencies": { "node-cron": "^3.0.0", "node-fetch": "^2.6.1", "webdav": "^4.11.2", "axios": "^0.27.2" } }<i> </i><e>

`.gitignore`

</s><i> </i>node_modules/ links.txt index.html<i> </i><e>