Closed huankong233 closed 1 year ago
抱歉最近不知道为什么总是收不到通知邮件
目前没有计划, 因为现在的写法和Cloudflare的耦合挺深的, 不是很好处理
如果是请求被CF拦截可以考虑调低防护等级什么的 具体是怎么被拦截的?
唔,怎么说呢,反正就是用nodejs的axios去请求cf page里的接口,要么403,要么就是502,但是我部署到本地请求就一点问题都没有了,具体可以看一眼我写的垃圾代码哈哈哈
文件位置:https://github.com/huankong233/kkbot/blob/master/plugins/dove/searchImage/index.js#L133 配置文件:https://github.com/huankong233/kkbot/blob/master/config/pigeon.jsonc#L46
我尝试过了一些别人提供的解决方案,都失败了,使用TLS1.1-1.2版本,并用postman的UA,在第一遍可以正常请求,但是到了第二次就又会被拦截
请求demo也会,我现在是直接部署到我自己的服务器上了,过段时间有空去看一眼然后抄一下
我尝试了一下,好像又被cf拦截了
C:\Users\huan_kong\Desktop\qqbot\bot\plugins\searchImage\libs>node ascii2d.js
Response {
size: 0,
[Symbol(Body internals)]: {
body: PassThrough {
_readableState: [ReadableState],
_events: [Object: null prototype],
_eventsCount: 6,
_maxListeners: undefined,
_writableState: [WritableState],
allowHalfOpen: true,
[Symbol(kCapture)]: false,
[Symbol(kCallback)]: null
},
stream: PassThrough {
_readableState: [ReadableState],
_events: [Object: null prototype],
_eventsCount: 6,
_maxListeners: undefined,
_writableState: [WritableState],
allowHalfOpen: true,
[Symbol(kCapture)]: false,
[Symbol(kCallback)]: null
},
boundary: null,
disturbed: false,
error: null
},
[Symbol(Response internals)]: {
type: 'default',
url: 'https://ascii2d.obfs.dev/search/file',
status: 500,
statusText: 'Internal Server Error',
headers: {
age: '0',
'alt-svc': 'h3=":443"; ma=86400, h3-29=":443"; ma=86400',
'cf-cache-status': 'DYNAMIC',
'cf-ray': '76e188866bc40439-HKG',
connection: 'close',
'content-type': 'text/html; charset=utf-8',
date: 'Tue, 22 Nov 2022 12:05:27 GMT',
nel: '{"success_fraction":0,"report_to":"cf-nel","max_age":604800}',
'report-to': '{"endpoints":[{"url":"https:\\/\\/a.nel.cloudflare.com\\/report\\/v3?s=M7cenqH1Ovqh9y0Y%2Fk8t8MdKRySjblBRaZ2UBkkrOaXWYhSa%2Bx20bq80hMHH1ltz0TU42kfXeTDfBqjcoUE%2Be88%2BBDWfGRR%2B8LkNxdPVcIPNJ3w%2F%2FuuuKeg21249Jh5tlkRR"}],"group":"cf-nel","max_age":604800}',
server: 'cloudflare',
'server-timing': 'cf-q-config;dur=7.0000005507609e-06',
'strict-transport-security': 'max-age=31536000',
'transfer-encoding': 'chunked',
vary: 'Accept-Encoding',
via: '1.1 varnish (Varnish/6.2)',
'x-content-type-options': 'nosniff',
'x-request-id': 'c4bf59b5-785c-4e09-9a2c-b9f2e260809c',
'x-runtime': '0.181728',
'x-varnish': '429952906'
},
counter: 0,
highWaterMark: 16384
}
}
这个是代码
import * as cheerio from 'cheerio'
export const BASE_URL = 'https://ascii2d.obfs.dev'
export function parse(body) {
const $ = cheerio.load(body, { decodeEntities: true })
return _.map($('.item-box'), item => {
const detail = $('.detail-box', item),
hash = $('.hash', item),
info = $('.info-box > .text-muted', item),
[image] = $('.image-box > img', item)
const [source, author] = $('a[rel=noopener]', detail)
if (!source && !author) return
return {
hash: hash.text(),
info: info.text(),
image: new URL(image.attribs['src'] ?? image.attribs['data-cfsrc'], BASE_URL).toString(),
source: source ? { link: source.attribs.href, text: $(source).text() } : undefined,
author: author ? { link: author.attribs.href, text: $(author).text() } : undefined
}
}).filter(v => v !== undefined)
}
import axios from 'axios'
import fetch from 'node-fetch'
async function post(req) {
const { type, image } = req
const Form = new FormData()
Form.append('file', image)
//返回的数据
let response = await fetch(`${BASE_URL}/search/file`, { method: 'POST', body: Form })
console.log(response)
// const colorResponse = await request.post(url, form)
// let response
// if (type === 'color') {
// response = await colorResponse.text()
// } else {
// const bovwUrl = colorResponse.url.replace('/color/', '/bovw/')
// response = await request.get(bovwUrl).then(res => res.text())
// }
return json(parse(response))
}
import { FormData } from 'formdata-polyfill/esm.min.js'
import fs from 'fs'
//色彩检索
const type = 'color'
//特征检索
// const type = 'bovw'
const image = fs.createReadStream('../123.png')
await post({ type, image })
500应该不是被拦了 应该是请求体什么写的不对 你再看看
嗯嗯,那我再去看看
这次应该真的是被拦截了( 信息有点多,就不全发出来了
_currentUrl: 'https://ascii2d.obfs.dev/search/file',
_timeout: null,
[Symbol(kCapture)]: false
},
[Symbol(kCapture)]: false,
[Symbol(kNeedDrain)]: false,
[Symbol(corked)]: 0,
[Symbol(kOutHeaders)]: [Object: null prototype] {
accept: [ 'Accept', 'application/json, text/plain, */*' ],
'content-type': [
'Content-Type',
'application/x-www-form-urlencoded;charset=utf-8'
],
'user-agent': [ 'User-Agent', 'axios/1.1.3' ],
'content-length': [ 'Content-Length', '24' ],
'accept-encoding': [ 'Accept-Encoding', 'gzip, deflate, br' ],
host: [ 'Host', 'ascii2d.obfs.dev' ]
}
},
data: '<!DOCTYPE html>\n' +
'<html>\n' +
'<head>\n' +
'<title>error (500)</title>\n' +
'<script src="/cdn-cgi/apps/head/w0I4DjwRjFMi1e1fsDNCyVDhib8.js"></script></head>\n' +
'<body>\n' +
'<h1>error (500)</h1>\n' +
`<script>(function(){var js = "window['__CF$cv$params']={r:'76e23d41386b9bf8',m:'tDEDQJVKEDGHumZSfYq8sxUwpITW8nraT4CCYXHHMDc-1669126138-0-ATwnB5j7PIRRrMj32A2jqGsii1/yppt6tRs+tWJ1PU0qARLEV+lKs2yM8SkWOnPJ7wTanZ4cxm1bgQE9p+B4aJlaVVjJPqWo0yn3fsVyPQti3EUVMJO9V/NZKps4tPcXww==',s:[0x44584262fd,0x6c3cfab7d5],u:'/cdn-cgi/challenge-platform/h/b'};var now=Date.now()/1000,offset=14400,ts=''+(Math.floor(now)-Math.floor(now%offset)),_cpo=document.createElement('script');_cpo.nonce='',_cpo.src='/cdn-cgi/challenge-platform/h/b/scripts/alpha/invisible.js?ts='+ts,document.getElementsByTagName('head')[0].appendChild(_cpo);";var _0xh = document.createElement('iframe');_0xh.height = 1;_0xh.width = 1;_0xh.style.position = 'absolute';_0xh.style.top = 0;_0xh.style.left = 0;_0xh.style.border = 'none';_0xh.style.visibility = 'hidden';document.body.appendChild(_0xh);function handler() {var _0xi = _0xh.contentDocument || _0xh.contentWindow.document;if (_0xi) {var _0xj = _0xi.createElement('script');_0xj.nonce = '';_0xj.innerHTML = js;_0xi.getElementsByTagName('head')[0].appendChild(_0xj);}}if (document.readyState !== 'loading') {handler();} else if (window.addEventListener) {document.addEventListener('DOMContentLoaded', handler);} else {var prev = document.onreadystatechange || function () {};document.onreadystatechange = function (e) {prev(e);if (document.readyState !== 'loading') {document.onreadystatechange = prev;handler();}};}})();</script><script defer src="https://static.cloudflareinsights.com/beacon.min.js/vaafb692b2aea4879b33c060e79fe94621666317369993" integrity="sha512-0ahDYl866UMhKuYcW078ScMalXqtFJggm7TmlUtp0UlD4eQk0Ixfnm5ykXKvGJNFjLMoortdseTfsRT8oCfgGA==" data-cf-beacon='{"rayId":"76e23d41386b9bf8","version":"2022.11.0","r":1,"token":"ce5a42621ac3434dacc5e4cab0b2c2d2","si":100}' crossorigin="anonymous"></script>\n` +
'</body>\n' +
'</html>\n'
}
}
async function post(req) {
const { type, image } = req
const Form = new URLSearchParams()
Form.append('file', image)
//返回的数据
let response = await axios({
method: 'post',
url: `${BASE_URL}/search/file`,
timeout: 60000,
// headers: {
// ...Form.getHeaders()
// },
data: Form
})
console.log(response)
}
或许我应该考虑传入url的方式来请求
IqDB如果不开启去除颜色会报错
import * as cheerio from 'cheerio'
import _ from 'lodash'
export const BASE_URL = 'https://iqdb.org/'
export function parse(body) {
const $ = cheerio.load(body)
return _.map($('table'), result => {
const content = $(result).text(),
[link] = $('td.image > a', result),
[image] = $('td.image img', result)
if (!link) return
const [, similarity] = content.match(/(\d+%)\s*similarity/),
//报错点
[, resolution, level] = content.match(/(\d+×\d+)\s*\[(\w+)\]/)
return {
url: new URL(link.attribs.href, BASE_URL).toString(),
image: new URL(image.attribs.src, BASE_URL).toString(),
similarity: parseFloat(similarity),
resolution,
level: level.toLowerCase()
}
})
.filter(v => v !== undefined)
.sort((a, b) => a.similarity - b.similarity)
.reverse()
}
import fetch from 'node-fetch'
import { FormData } from 'formdata-node'
import { fileFromPath } from 'formdata-node/file-from-path'
export async function post(req) {
const { services, discolor, imagePath } = req
const form = new FormData()
form.append('file', await fileFromPath(imagePath))
if (services) services.forEach((s, index) => form.append(`service.${index}`, s.toString()))
if (discolor) form.append('forcegray', 'on')
const response = await fetch(BASE_URL, { method: 'POST', body: form }).then(res => res.text())
console.log(response)
return parse(response)
}
const response = await post({
// discolor: true,
// 为false时会报错
discolor: true,
imagePath: '../123.png',
services: [
'danbooru',
'konachan',
'yandere',
'gelbooru',
'sankaku_channel',
'e_shuushuu',
'zerochan',
'anime_pictures'
]
})
console.dir(response, { depth: null })
比如https://vercel.com/ 因为我想要使用网站的接口,但是被cloudflare拦截了,不知道怎样绕过