pvcep_rules

Rules for /scripts/24204-Picviewer-CE-plus

目前为 2024-05-26 提交的版本。查看 最新版本

此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.sleazyfork.org/scripts/438080/1383444/pvcep_rules.js

  1. /*
  2. PVCEP - Rules for Picviewer CE+
  3. <https://github.com/hoothin/UserScripts/blob/master/Picviewer%20CE%2B/pvcep_rules.js>
  4.  
  5. (c) 2021-2024 Hoothin <rixixi [at] gmail.com>
  6. Licenced under the MIT license.
  7.  
  8. 最少僅需
  9. {
  10. name: 站點名
  11. r: 圖片地址正則或者待替換字符串,如果是陣列則代表多個替換規則
  12. s: 替換目標字符串
  13. }
  14. 或者
  15. {
  16. name: 站點名
  17. getImage(a, p): 指向圖片時的地址替換函數,a 為第一個父級A元素,p 為所有父級元素的陣列,詳情見下方例子
  18. }
  19. 其他參數項按需添加即可。
  20. 需要注意 css/ext/xhr/lazyAttr(懶加載的原圖 URL 屬性名)/description(收藏圖片時的描述,支持選擇器或 xpath)/clickToOpen 在指定 url 之後方可使用
  21. xhr 為內頁圖片獲取屬性。
  22. 1. 首先使用 xhr.url() 篩選並返回父級 a 標籤的 url,然後腳本會自動抓取該 url 指向的網頁。
  23. 2. 透過 xhr 獲取圖片。
  24. 2.1 其中 xhr.query 為圖片(可以為多張,多張將添加到圖庫)的選擇器或者函數
  25. 2.2 xhr.caption 為圖片的文字描述,抓取方式同上
  26. 如果鼠標指向對象非圖片,可使用 getExtSrc 生成想要的圖片地址,詳情見下方 youtube 例子
  27. ext 為滑鼠指向非圖片元素時抓取附近圖片元素的方式,"previous" 代表檢測上一個兄弟節點,"previous-2" 代表檢測前數第二個兄弟節點,"next" 代表檢測下一個兄弟節點
  28. getExtSrc 為根據非圖片元素直接獲取圖片 URL 的方法
  29.  
  30. #####################################################################################
  31.  
  32. minimum
  33. {
  34. name: site name
  35. r: regular image url or string to be replaced
  36. s: replacement target string
  37. }
  38. or
  39. {
  40. name: site name
  41. getImage(a, p): Replace the image URL when pointing to an image, 'a' refers to the first parent A element, and 'p' is an array of all parent elements, see the example below for details
  42. }
  43. Other parameter items can be added as needed.
  44. Note that css/ext/xhr/lazyAttr (lazy loaded original image URL attribute name)/description (description when collecting images, support selector or xpath)/clickToOpen should only be used after specifying the url.
  45. xhr is used to obtain the attributes of the pictures on the inner pages.
  46. 1. First, use xhr.url() to filter and return the url of the parent a tag, and then the script will automatically grab the webpage pointed to by the url.
  47. 2. And get pictures through xhr.
  48. 2.1 xhr.query is the picture (you can For multiple, multiple will be added to the gallery) selector or function
  49. 2.2 xhr.caption is the description of picture
  50. If the mouse points to an object other than a picture, you can use getExtSrc to generate the desired picture url, see the youtube example below for details
  51. ext is the method for capturing nearby image elements when the mouse hovers over a non-image element. "previous" indicates detecting the previous sibling node, "previous-2" indicates detecting the second sibling node in reverse order, and "next" indicates detecting the next sibling node.
  52. getExtSrc is the method for directly obtaining the image URL based on a non-image element.
  53. */
  54. var siteInfo = [
  55. {
  56. name: "google 图片搜索",
  57.  
  58. //網址例子 ( 方便測試和查看 )
  59. example: "http://www.google.com.hk/search?q=firefox&tbm=isch",
  60.  
  61. //是否啟用
  62. enabled: true,
  63.  
  64. //站點正則,匹配站點url該條規則才會生效
  65. url: /https?:\/\/www.google(\.\w{1,3}){1,3}\/search\?.*&(tbm=isch|udm=2)/,
  66.  
  67. //鼠標點擊直接打開(僅當高級規則的getImage()或者r/s替換有返回值的時候生效)
  68. clickToOpen: {
  69. enabled: false,
  70. preventDefault: true,//是否嘗試阻止點擊的默認行為(比如如果是你點的是一個鏈接,默認行為是打開這個鏈接,如果是true,js會嘗試阻止鏈接的打開(如果想臨時打開這個鏈接,請使用右鍵的打開命令))
  71. button: 0,//0:鼠標左鍵 1:滾輪按鈕或中間按鈕(如果有) 2:鼠標右鍵。默認為 0
  72. alt: false,//是否需要按下alt鍵
  73. ctrl: false,//是否需要按下ctrl鍵
  74. shift: false,//是否需要按下shift鍵
  75. meta: false,//是否需要按下meta鍵
  76. type: 'actual',//默認的打開方式: 'actual'(彈出,原始圖片) 'magnifier'(放大鏡) 'current'(彈出,當前圖片)
  77. },
  78.  
  79. //獲取圖片實際地址的處理函數,
  80. //this 為當前鼠標懸浮圖片的引用,
  81. //第一個參數為當前圖片的父元素中第一個a元素(可能不存在)
  82. //第二個參數為保存當前圖片所有父元素的數組
  83. getImage: function(a) {
  84. if(!a) return;
  85. let jsaction = a.getAttribute("jsaction");
  86. if (a.href.match(/imgurl=(.*?)&/i)) {
  87. return decodeURIComponent(RegExp.$1);
  88. } else if (jsaction && jsaction.indexOf('touchstart') !== -1) {
  89. const touchList = [new Touch({
  90. identifier: 1,
  91. target: document.documentElement,
  92. clientX: 0,
  93. clientY: 0
  94. })];
  95. var fakeEvent = new TouchEvent('touchstart', {bubbles: true, touches: touchList});
  96. a.dispatchEvent(fakeEvent);
  97. fakeEvent = new TouchEvent('touchend', {bubbles: true});
  98. a.dispatchEvent(fakeEvent);
  99. if (a.href.match(/imgurl=(.*?)&/i)) {
  100. return decodeURIComponent(RegExp.$1);
  101. }
  102. }
  103. }
  104.  
  105. // 自定義樣式
  106. // css: '',
  107.  
  108. // 如果圖片藏在非img標籤後面,使用此項獲取被遮擋的img元素。
  109. // 其中previous代表前面一個元素,previous-2代表前面第二個元素,next代表後面一個元素。
  110. // 或者直接用函數獲取,傳入當前元素,返回查找到的元素或是null。
  111. // ext: 'previous-2',
  112.  
  113. // 排除的圖片正則
  114. // exclude: /weixin_code\.png$/i,
  115.  
  116. // 需要替換的圖片正則,匹配上圖片url該條規則才生效
  117. // src: /avatar/i,
  118.  
  119. // 正則或字符串檢測內容,可以為含有多組規則的數組,若為字符串則只進行字符串替換
  120. // r: /\?.*$/i,
  121.  
  122. // 正則或字符串替換內容,可以與上一條一一對應,也可以以數組對應檢測正則的其中一條,比如希望有多個結果嘗試顯示原圖
  123. // s: ''
  124. },
  125. {
  126. name: "123rf",
  127. url: /123rf\.com/,
  128. r: /us\.123rf\.com\/\d+wm\//i,
  129. s: "previews.123rf.com/images/"
  130. },
  131. {
  132. name: "126",
  133. src: /\.126\.net/i,
  134. r: /\/\d+\.\d+x\d+\.\d+\.([^\.]+)$/i,
  135. s: '/5.5000x5000.100.$1'
  136. },
  137. {
  138. name:"178.com",
  139. enabled:true,
  140. url:/^https?:\/\/(?:\w+\.)+178\.com\//i,
  141. clickToOpen:{
  142. enabled:true,
  143. preventDefault:true,
  144. type:'actual',
  145. },
  146. getImage:function(a){
  147. if(!a)return;
  148. var reg=/^https?:\/\/(?:\w+\.)+178\.com\/.+?(https?:\/\/img\d*.178.com\/[^.]+\.(?:jpg|jpeg|png|gif|bmp))/i;
  149. return (a.href.match(reg) || [])[1];
  150. }
  151. },
  152. {
  153. name: "24meitu",
  154. url: /24meitu\.com|25meinv\.com|aisimeinv\.com|24tupian\.com|24meinv\.|24mntp\.|24cos\.|24fh\.|24shipin\.|24mn\./,
  155. r: [/\/m([^\/]+)$/i,
  156. /imgs\./i],
  157. s: ["/$1","bimg."]
  158. },
  159. {
  160. name: "bing 图片搜索",
  161. example:"http://cn.bing.com/images/search?q=%E7%BE%8E%E5%A5%B3",
  162. enabled:true,
  163. url: /^https?:\/\/[^.]*\.bing\.com\/images\//i,
  164. getImage:function(a){
  165. if (!a) return;
  166. var oldsrc=this.src;
  167. var $ = /,imgurl:"([^"]+)/.exec(a.getAttribute('m'));
  168. var newsrc= $ ? $[1] : '';
  169. if(newsrc!=oldsrc)return newsrc;
  170. }
  171. },
  172. {
  173. name:"百度贴吧",
  174. enabled:true,
  175. url:/^https?:\/\/tieba\.baidu\.[^\/]+\//i,
  176. r: [/\/sys\/portrait/i,
  177. /^(http:\/\/tiebapic\.baidu\.com\/forum\/)ab(pic\/item\/[\w.]+)/i],
  178. s: ["/sys/portraitl", "$1$2"],
  179. getImage: function(a, p) {
  180. let bsrc = this.getAttribute('bpic');
  181. return bsrc || null;
  182. },
  183. xhr: {
  184. url: function(a, p) {
  185. let pid = this.src.match(/\.baidu\.com\/forum\/w.*\/(\w+)\./);
  186. if (!pid) return null;
  187. pid = pid[1];
  188. let tid = 0;
  189. let tidm = location.href.match(/\/p\/(\d+)/);
  190. if (tidm) tid = tidm[1];
  191. if (tid) {
  192. let kw = document.querySelector(`#wd2`);
  193. if (kw && kw.value) {
  194. return `https://tieba.baidu.com/photo/bw/picture/guide?kw=${kw.value}&tid=${tid}&pic_id=${pid}&see_lz=0&from_page=0&alt=jview`;
  195. }
  196. }
  197. return null;
  198. },
  199. query: function(html, doc, url) {
  200. let data = JSON.parse(html);
  201. if (!data) return null;
  202. let pid = url.match(/&pic_id=(\w+)/)[1];
  203. for (let key in data.data.pic_list) {
  204. let pic = data.data.pic_list[key];
  205. if (pic.img.screen.id == pid) return pic.img.screen.waterurl;
  206. }
  207. return null;
  208. }
  209. }
  210. },
  211. {
  212. name: "百度图片搜索",
  213. example: "http://image.baidu.com/i?ie=utf-8&word=%E9%A3%8E%E6%99%AF&oq=%E9%A3%8E%E6%99",
  214. enabled: true,
  215. url: /^https?:\/\/image\.baidu\.com\/.*&word=/i,
  216. getImage: function(a) {
  217. if (!a) return;
  218. var reg = /&objurl=(http.*?\.(?:jpg|jpeg|png|gif|bmp))/i;
  219. if (a.href.match(reg)) {
  220. return decodeURIComponent(RegExp.$1);
  221. }
  222. }
  223. },
  224. {
  225. name:"豆瓣",
  226. example:"http://movie.douban.com/photos/photo/1000656155/",
  227. enabled: true,
  228. url:/^https?:\/\/[^.]*\.douban\.com/i,
  229. getImage:function(){
  230. var oldsrc = this.src,
  231. newsrc = oldsrc;
  232. var pic = /\/view\/photo\/(?:photo|albumcover|albumicon|thumb|sqxs)\/public\//i;
  233. var movieCover = /\/view\/movie_poster_cover\/[si]pst\/public\//i;
  234. var bookCover = /\/view\/ark_article_cover\/cut\/public\//i;
  235. var spic = /(img\d+.douban.com)\/[sm]pic\//i;
  236. var ratio = /s_ratio_poster/i;
  237. if(/\/subject\/\d+\/discussion/.test(location.href)){
  238. } else if (pic.test(oldsrc)) {
  239. newsrc = oldsrc.replace(pic, '/view/photo/raw/public/');
  240. } else if (movieCover.test(oldsrc)) {
  241. newsrc = oldsrc.replace(movieCover, '/view/photo/raw/public/');
  242. } else if (bookCover.test(oldsrc)) {
  243. newsrc = oldsrc.replace(bookCover, '/view/ark_article_cover/retina/public/');
  244. } else if (spic.test(oldsrc)) {
  245. newsrc = oldsrc.replace(spic, '$1/lpic/');
  246. } else if (ratio.test(oldsrc)) {
  247. newsrc = oldsrc.replace(ratio, 'l');
  248. }
  249. return newsrc == oldsrc ? null : [newsrc,newsrc.replace(/photo\/raw/,"photo/photo")];
  250. }
  251. },
  252. {
  253. name:"bilibili",
  254. enabled:true,
  255. url:/^https?:\/\/[^.]+\.bilibili.com/i,
  256. ext: function(target) {
  257. if(target && target.parentNode){
  258. return target.parentNode.querySelector("img");
  259. }
  260. },
  261. r: /\d+_\d+\/|\d+_x\d+\.jpg$|@\d+w_\d+h.*\.webp$|_\d+x\d+\.jpg$/i,
  262. s: ""
  263. },
  264. /*{
  265. name: "deviantart",
  266. example: "http://www.deviantart.com",
  267. enabled:true,
  268. url:/^https?:\/\/[^.]*\.deviantart\.com/i,
  269. getImage:function(a, p){
  270. let id,self=this;
  271. if(p[1] && p[1].dataset.hook=="deviation_link"){
  272. id=p[1].href.replace(/.*?(\d+)$/,"$1");
  273. }else if(p[2] && p[2].dataset.hook=="deviation_link"){
  274. id=p[2].href.replace(/.*?(\d+)$/,"$1");
  275. }
  276. if(/\?token/.test(this.src)){
  277. if(!this.dataset.pvsrc && id){
  278. this.dataset.pvsrc="t";
  279. GM_xmlhttpRequest({
  280. method: 'get',
  281. responseType: "json",
  282. url: '/_napi/shared_api/deviation/extended_fetch?deviationid='+id+'&type=art&include_session=false',
  283. onload: function(d) {
  284. var media = (d.response && d.response.deviation)?d.response.deviation.media:null;
  285. var fullview = media && media.types && media.types.find(t=>{return t.t=='fullview'});
  286. if(media && media.baseUri && fullview && media.token){
  287. var resultUrl=media.baseUri+(fullview.c?fullview.c.replace("<prettyName>",media.prettyName).replace(/,q_\d+/,",q_100"):"")+"?token="+media.token[0];
  288. self.dataset.pvsrc=resultUrl;
  289. if(floatBar){
  290. floatBar.update(self, self.dataset.pvsrc);
  291. }
  292. }
  293. }
  294. });
  295. }else if(this.dataset.pvsrc!="t" && id){
  296. return this.dataset.pvsrc;
  297. }
  298. }
  299. return null;
  300. },
  301. },
  302. {
  303. name:"deviantart",
  304. url:/^https?:\/\/[^.]*\.deviantart\.com/i,
  305. xhr: {
  306. url: 'a[data-hook = "deviation_link"]',
  307. query: '[property="contentUrl"]'
  308. }
  309. },*/
  310. {
  311. name:"deviantart",
  312. url:/^https?:\/\/[^.]*\.deviantart\.com/i,
  313. getImage: function(a, p) {
  314. if (!a) return;
  315. let media =Object.keys(a).filter(prop => prop.indexOf("__reactProps") === 0);
  316. if (!media || !a[media] || !a[media].children || !a[media].children.props || !a[media].children.props.deviation) return;
  317. media = a[media].children.props.deviation.media;
  318. let fullview = media.types.filter(d => d.t === "fullview");
  319. let ext = media.baseUri.match(/\.\w+$/);
  320. if (!fullview || !ext) return;
  321. fullview = fullview[0];
  322. ext = ext[0];
  323. return media.baseUri + `/v1/fill/w_${fullview.w},h_${fullview.h}/${media.prettyName}-fullview${ext}?token=` + media.token[0];
  324. }
  325. },
  326. {
  327. name: '花瓣网',
  328. enabled: true,
  329. url: /^https?:\/\/huaban\.com\//i,
  330. ext: 'previous-2',
  331. r: /(.*img.hb.aicdn.com\/.*)_fw(?:236|320)$/i,
  332. s: '$1_fw658',
  333. description: './../following-sibling::p[@class="description"]',
  334. // css: '.pin a.img .cover { display: none; }',
  335. exclude: /weixin_code\.png$/i,
  336. },
  337. {
  338. name: "wikipedia",
  339. enabled:true,
  340. url:/^https?:\/\/.+\.wikipedia\.org\//i,
  341. r: /(https?:\/\/.*)\/thumb(\/.*)\/\d+px-.*/i,
  342. s: "$1$2"
  343. },
  344. {
  345. name:"沪江碎碎",
  346. enabled:true,
  347. url:/^https?:\/\/([^.]+\.)*(?:yeshj\.com|hjenglish\.com|hujiang\.com)/i,
  348. r: /^(https?:\/\/(?:[^.]+\.)*hjfile.cn\/.+)(_(?:s|m))(\.\w+)$/i,
  349. s: '$1$3'
  350. },
  351. {
  352. name: '大众点评',
  353. example: 'http://www.dianping.com/shop/17873296/photos',
  354. url: /^https?:\/\/www.dianping.com\/shop/i,
  355. r: /(.+?dpfile\.com\/.+)\(240c180\)\/(thumb\..+)/i,
  356. s: '$1(700x700)/$2'
  357. },
  358. {
  359. name: 'trakt.tv',
  360. url: /^http:\/\/trakt\.tv\//i,
  361. example: 'http://trakt.tv/shows',
  362. r: /(.*\/images\/posters\/\d+)-(?:300|138)\.jpg\?(\d+)$/i,
  363. s: "$1.jpg?$2"
  364. },
  365. {
  366. name: '网易云音乐',
  367. url: 'https://music.163.com/*',
  368. ext: 'previous',
  369. getImage: function() {
  370. var oldsrc = this.src;
  371. if(this.data){
  372. var newsrc = this.data('src');
  373. if (oldsrc != newsrc) {
  374. return newsrc;
  375. }
  376. }
  377. if (oldsrc.match(/(.*)\?param=\d+y\d+/)) {
  378. return RegExp.$1;
  379. }
  380. }
  381. },
  382. {
  383. name: "美女薄情馆",
  384. url: /^http:\/\/boqingguan\.com\//i,
  385. example: 'http://boqingguan.com/Picture/31637',
  386. lazyAttr: 'data-original',
  387. getImage: function(a) {
  388. var oldsrc = this.getAttribute('data-original') || this.src;
  389. if (oldsrc) {
  390. var newsrc = oldsrc.replace(/![a-z\d]+$/, '');
  391. return newsrc == oldsrc ? '' : newsrc;
  392. }
  393. }
  394. },
  395. {
  396. name:"极限主题社区",
  397. enabled:true,
  398. url:/^https?:\/\/bbs\.themex\.net\/.+/i,
  399. clickToOpen:{
  400. enabled:true,
  401. preventDefault:true,
  402. type:'actual',
  403. },
  404. r: /^(https?:\/\/bbs\.themex\.net\/attachment\.php\?.+)&thumb=1(.+)/i,
  405. s: '$1$2'
  406. },
  407. {
  408. name:"opera官方论坛",
  409. example:"http://bbs.operachina.com",
  410. enabled:true,
  411. url:/^http:\/\/bbs\.operachina\.com/i,
  412. src: /file.php\?id=\d+$/i,
  413. r: /.*/,
  414. s: "$1&mode=view"
  415. },
  416. {
  417. name: 'github 修正',
  418. url: /^https?:\/\/github\.com\//i,
  419. clickToOpen: {
  420. enabled: false,
  421. preventDefault: true,
  422. type: 'actual',
  423. },
  424. getImage: function(a) {
  425. if (a && a.href.indexOf('/blob/master/') > 0) {
  426. return this.src;
  427. }
  428. }
  429. },
  430. {
  431. name: '优美图',
  432. url: /http:\/\/(?:www\.)?topit\.me\//,
  433. lazyAttr: 'data-original',
  434. xhr: {
  435. url: /topit\.me\/item\/\d+/,
  436. query: ['a[download]', 'a#item-tip'],
  437. }
  438. },
  439. {
  440. name: '半次元',
  441. url: /^https?:\/\/bcy\.net\//,
  442. r: [/\/\dX\d$|\/w\d+$/i,
  443. "/cover/",
  444. /\/(middle|small)\.jpg/i],
  445. s: ["", "/post/", "/big.jpg"]
  446. },
  447. {
  448. name: 'Steampowered',
  449. url: /\.steampowered\.com/,
  450. r: /\.\d+x\d+\.jpg/i,
  451. s: ".jpg"
  452. },
  453. {
  454. name: 'Steamcommunity',
  455. url: /steamcommunity\.com/,
  456. r: /output\-quality=\d+&fit=inside\|\d+\:\d+/i,
  457. s: "output-quality=100&fit=inside|0:0"
  458. },
  459. {
  460. name: '知乎',
  461. url: /(zhihu|zhimg)\.com/,
  462. r: /_(b|xs|s|l|\d+x\d+)\./i,
  463. s: "."
  464. },
  465. {
  466. name: '500px',
  467. url: /500px\./,
  468. r: [/\/w%3D\d+_h%3D\d+\/v2.*/i,
  469. /^((?:(?:pp?cdn|s\\d\\.amazonaws\\.com\/photos|gp\\d+\\.wac\\.edgecastcdn\\.net\/806614\/photos\/photos)\\.500px|djlhggipcyllo\\.cloudfront)\\.(?:net|org)\/\\d+\/[\\da-f]{40}\/)\\d+\\./],
  470. s: ["/m%3D2048_k%3D1_of%3D1/v2",
  471. "$12048.jpg"]
  472. },
  473. {
  474. name: 'Nyaa',
  475. url: /nyaa\.se/,
  476. r: /upload\/small\//i,
  477. s: "upload/big/"
  478. },
  479. {
  480. name: "itunes",
  481. url: /itunes\.apple\.com/,
  482. r: /\d+x\d+bb\./i,
  483. s: "1400x1400bb."
  484. },
  485. {
  486. name: "汽车之家",
  487. url: /\.autohome\.com\.cn/,
  488. r: /(\?imageView.*|\d+x\d+_\d+_|f_m_|t_|s_)/i,
  489. s: ""
  490. },
  491. {
  492. name: "易车",
  493. url: /\.bitauto\.com/,
  494. r: /_\d+\.jpg$/i,
  495. s: "_12.jpg"
  496. },
  497. {
  498. name: "爱卡",
  499. url: /\.xcar\.com\.cn/,
  500. r: /\-\d+x\d+\.jpg/i,
  501. s: ""
  502. },
  503. {
  504. name: "太平洋汽车",
  505. url: /\.pcauto\.com\.cn/,
  506. r: /_\d+x\d+\.jpg$/i,
  507. s: ".jpg"
  508. },
  509. {
  510. name: "新浪汽车",
  511. url: /\.auto\.sina\.com\.cn/,
  512. r: /_\d+\.jpg$/i,
  513. s: "_src.jpg"
  514. },
  515. {
  516. name: "greasyfork",
  517. url: /(greasyfork|sleazyfork)\.org/,
  518. getImage: function() {
  519. if(this.parentNode.nodeName=="A" && /amazonaws\.com/.test(this.parentNode.href)){
  520. return this.parentNode.href;
  521. }
  522. return this.src.replace(/\/thumb\//i,"/original/").replace(/\/thumbnails\//i,"/").replace(/(\/forum\/uploads\/userpics\/.*\/)n([^\/]+)$/,"$1p$2");
  523. }
  524. },
  525. {
  526. name: "dribbble",
  527. url: /dribbble\.com/,
  528. r: [/_teaser(.[^\.]+)$/i,
  529. /_1x\./i,
  530. /\?compress=.*/],
  531. s: ["$1",".",""]
  532. },
  533. {
  534. name: "百度百科",
  535. url: /baike\.baidu\.com/,
  536. r: [/.*bdstatic\.com.*\/([^\/]+)\.jpg/i,
  537. /(.*bkimg\.cdn\.bcebos\.com.*\?x-bce-process=image).*/i],
  538. s: ["http://imgsrc.baidu.com/baike/pic/item/$1.jpg",
  539. "$1"]
  540. },
  541. {
  542. name: "nvshens",
  543. url: /nvshens\.com|onvshen\.com/,
  544. r: /(\img\.onvshen\.com.*)(?:thumb\/|_s)(.*)/i,
  545. s: "$1$2"
  546. },
  547. {
  548. name: "Tumblr",
  549. url: /tumblr\.com/,
  550. exclude: /\/avatar_/i,
  551. r: /[^\/]*(media\.tumblr\.com.*_)\d+(\.[^\.]+)$/i,
  552. s: "$1raw$2"
  553. },
  554. {
  555. name: "Tumblr",
  556. url: /tumblr\.com/,
  557. src: /\/avatar_/i,
  558. r: /(media\.tumblr\.com.*_)[^_]+(\.[^\.]+)$/i,
  559. s: "$1512$2"
  560. },
  561. {
  562. name: "Acgget",
  563. url: /acg18\.us|acgget\./,
  564. r: /(pic\.acgget\.com\/thumb\/)w\d+_h\d+\//i,
  565. s: "$1w9999_h9999/"
  566. },
  567. {
  568. name: "Pixiv",
  569. url: /pixiv\.net|pximg\.net/,
  570. src: /pximg\.net\/c\/\d+x\d+/i,
  571. r: /pximg\.net\/c\/\d+x\d+.*\/img\/(.*)_.*$/i,
  572. s: ["pximg.net/img-original/img/$1.jpg","pximg.net/img-original/img/$1.png"]
  573. },
  574. {
  575. name: "Wallhaven",
  576. url: /wallhaven\./,
  577. src: /wallpapers\/thumb\/small\/th|th\.wallhaven\.cc\/(small|lg)\//i,
  578. r: [/wallpapers\/thumb\/small\/th(.*)\./i,
  579. /th\.wallhaven\.cc\/(small|lg)\/(.*)?\/(.*)\..*/i],
  580. s: [["wallpapers/full/wallhaven$1.jpg","wallpapers/full/wallhaven$1.png"],
  581. ["w.wallhaven.cc/full/$2/wallhaven-$3.jpg","w.wallhaven.cc/full/$2/wallhaven-$3.png"]],
  582. getImage() {
  583. let srcReg1 = /wallpapers\/thumb\/small\/th(.*)\./i;
  584. let srcReg2 = /th\.wallhaven\.cc\/(small|lg)\/(.*)?\/(.*)\..*/i;
  585. let res1 = "wallpapers/full/wallhaven$1.";
  586. let res2 = "w.wallhaven.cc/full/$2/wallhaven-$3.";
  587. let png, ne;
  588. if (this.nextElementSibling && this.nextElementSibling.nextElementSibling) {
  589. ne = this.nextElementSibling.nextElementSibling;
  590. if (ne.className != "thumb-info") ne = null;
  591. else png = !!ne.querySelector('.png');
  592. }
  593. if (srcReg1.test(this.src)) {
  594. return ne ? this.src.replace(srcReg1, res1 + (png ? "png" : "jpg")) : [this.src.replace(srcReg1, res1 + "jpg"), this.src.replace(srcReg1, res1 + "png")];
  595. }
  596. if (srcReg2.test(this.src)) {
  597. return ne ? this.src.replace(srcReg2, res2 + (png ? "png" : "jpg")) : [this.src.replace(srcReg2, res2 + "jpg"), this.src.replace(srcReg2, res2 + "png")];
  598. }
  599. }
  600. },
  601. {
  602. name: "lofter",
  603. url: /lofter\./,
  604. getImage: function(a) {
  605. if(a && a.href && a.hasAttribute("bigimgsrc")){
  606. return a.getAttribute("bigimgsrc");
  607. }
  608. return this.src.replace(/\?.*/i,"");
  609. }
  610. },
  611. {
  612. name: "sohu",
  613. url: /(sohu|sohucs)\.com/,
  614. r: /(sohucs\.com\/).*\/(images\/|os\/)/i,
  615. s: "$1$2"
  616. },
  617. {
  618. name: "moegirl",
  619. url: /(moegirl|mengniang)\.org/,
  620. r: /(common)\/thumb(.*)\/[^\/]+/i,
  621. s: "$1$2"
  622. },
  623. {
  624. name: "fanfou",
  625. url: /fanfou\.com/,
  626. r: /@.+/i,
  627. s: ""
  628. },
  629. {
  630. name: "meitudata",
  631. url: /meipai\.com/,
  632. r: /!thumb.+/i,
  633. s: ""
  634. },
  635. {
  636. name: "mafengwo",
  637. url: /mafengwo\.cn/,
  638. r: /\?imageMogr.*/i,
  639. s: ""
  640. },
  641. {
  642. name: "discordapp",
  643. url: /(discordapp\.|discord\.)(com|net)/,
  644. r: /\?width=\d+&height=\d+$/i,
  645. s: ""
  646. },
  647. {
  648. name: "推特",
  649. url: /https:\/\/(www\.)?(x|twitter)\.com|pbs\.twimg\.com/,
  650. description: ["./..", "aria-label"],
  651. getImage: function(a, p){
  652. let newsrc = this.src.replace("_normal.",".").replace("_200x200.",".").replace("_mini.",".");
  653. if (newsrc != this.src)return newsrc;
  654. newsrc=newsrc.replace(/\?format=/i, ".").replace(/\&name=/i, ":").replace(/\.(?=[^.]*$)/, "?format=").replace( /(:large|:medium|:small|:orig|:thumb|:[\dx]+)/i, "");
  655. if (newsrc != this.src) {
  656. if (a && a.role == 'link') {
  657. let match = a.href.match(/\/([^\/]+)\/status\/([^\/]+)\/photo\/(\d+)/);
  658. if (match) {
  659. let time = p[14] && p[14].querySelector('time');
  660. if (time) {
  661. this.alt = match[1] + " - " + time.innerText + "_" + match[3];
  662. }
  663. }
  664. }
  665. return newsrc+"&name=orig";
  666. }
  667. },
  668. ext: function(target) {
  669. if(target.parentNode && target.parentNode.previousElementSibling){
  670. let imgs=target.parentNode.previousElementSibling.querySelectorAll("img");
  671. if(imgs.length==1)return imgs[0];
  672. }
  673. return null;
  674. }
  675. },
  676. {
  677. name: "Fandom",
  678. url: /fandom\.com/,
  679. r: [/scale\-to\-width\-down\/\d+/i,
  680. /smart\/width\/\d+\/height\/\d+/i],
  681. s: ["",""]
  682. },
  683. {
  684. name: "yande",
  685. url: /yande\.re|konachan\.(net|com)/,
  686. getImage: function(a, p) {
  687. if(p[1] && p[1].nextSibling && p[1].nextSibling.classList &&
  688. p[1].nextSibling.classList.contains("largeimg")){
  689. return p[1].nextSibling.href.replace(/\/(preview|jpeg|sample)\/(.*\.)jpg$/, "/image/$2png");
  690. }
  691. return this.src.replace(/\/(preview|jpeg|sample)\/(.*\.)jpg$/, "/image/$2png");
  692. }
  693. },
  694. {
  695. name:"绅士漫画",
  696. url:/^https?:\/\/(www\.)?wnacg\./,
  697. src: /\/\/t(\w\.qy.*data\/)t\//,
  698. r: /\/\/t(\w\.qy.*data\/)t\//,
  699. s: "//img$1",
  700. xhr: {
  701. url: function(a, p) {
  702. if (p && p[1] && p[1].className === 'pic_box tb' && a && a.href) {
  703. return a.href;
  704. }
  705. },
  706. query: '#picarea'
  707. }
  708. },
  709. {
  710. name:"xlysauc",
  711. url:/^https?:\/\/xlysauc\.com\//,
  712. r: /\/x\/(\d+\.jpg)/,
  713. s: "/d/$1",
  714. ext: function(target) {
  715. if (target.parentNode.className === 'imgbg' || target.className === 'pp_hoverContainer'){
  716. let img = target.parentNode.querySelector("img");
  717. if (img) return img;
  718. }
  719. return null;
  720. }
  721. },
  722. {
  723. name: "E621",
  724. url: /e621\.net/,
  725. getImage: function(a, p) {
  726. if(p[2] && p[2].dataset.fileUrl){
  727. return p[2].dataset.fileUrl;
  728. }
  729. return this.src;
  730. }
  731. },
  732. {
  733. name: "Pinterest",
  734. url: /pinterest\.com/,
  735. getImage: function(a, p) {
  736. if(this.srcset){
  737. var srcs=this.srcset.split(","),minSize=0,newSrc;
  738. srcs.forEach(srci=>{
  739. let srcInfo=srci.trim().split(" "),curSize=parseInt(srcInfo[1]);
  740. if(srcInfo[1] && (curSize>minSize || minSize==0)){
  741. minSize=curSize;
  742. newSrc=srcInfo[0];
  743. }
  744. });
  745. if(newSrc)return newSrc;
  746. }
  747. return this.src.replace(/\/\d+x\//i, "/736x/");
  748. }
  749. },
  750. {
  751. name: "Zhisheji",
  752. url: /zhisheji\.com/,
  753. r: /thumbnail\/.*/i,
  754. s: ""
  755. },
  756. {
  757. name: "imgbox",
  758. src: /imgbox\.com/,
  759. r: /thumbs(\d\.imgbox.*)_t\./i,
  760. s: "images$1_o."
  761. },
  762. {
  763. name: "Reddit",
  764. url: /reddit\.com|redd\.it/,
  765. getImage: function() {
  766. if (this.srcset) {
  767. var srcs = this.srcset.split(/[xw],/i);
  768. for (let i = 0; i < srcs.length; i++) {
  769. let srcInfo = srcs[i].trim().split(" ")[0];
  770. if (srcInfo.indexOf("?width") == -1) return srcInfo;
  771. }
  772. }
  773. return this.src;
  774. },
  775. xhr: {
  776. url: function(a, p, self) {
  777. if (a && a.href && /\/\/v.redd\.it\/\w+\/?$/.test(a.href)) {
  778. return a.href + '/DASHPlaylist.mpd';
  779. } else if (a && a.href && /^https:\/\/www\.reddit\.com\/gallery\//.test(a.href)) {
  780. return a.href;
  781. } else if (a && a.href && /redgifs\.com\//.test(a.href)) {
  782. const apiUrl = 'https://api.redgifs.com/v2';
  783. if (!self.redgifsToken) {
  784. self.redgifsToken = "1";
  785. fetch(`${apiUrl}/auth/temporary`).then(res => res.json()).then((data) => {
  786. if (data && data.token) {
  787. self.redgifsToken = data.token;
  788. }
  789. });
  790. }
  791. return apiUrl + "/gifs/" + a.href.replace(/.*redgifs.com\/(..\/)?(\w+\/)?(\w+)(?:\.\w+)?/, '$3');;
  792. }
  793. },
  794. headers: (url, self) => {
  795. if (/redgifs\.com\//.test(url)) {
  796. return { Authorization:`Bearer ${self.redgifsToken}` };
  797. }
  798. },
  799. query: function(html, doc, url) {
  800. try {
  801. if (/redgifs\.com\//.test(url)) {
  802. let data;
  803. try {
  804. data = JSON.parse(html);
  805. } catch (e) {
  806. return;
  807. }
  808. if (data && data.gif) {
  809. return data.gif.urls.gif || data.gif.urls.hd;
  810. }
  811. } else if (/^https:\/\/www\.reddit\.com\/gallery\//.test(url)) {
  812. return [].reduce.call(doc.querySelectorAll("figure>a"), (total, cur) => {
  813. return total.concat(cur.href);
  814. }, []);
  815. }
  816. var xmlDoc = (new DOMParser()).parseFromString(html, 'application/xml');
  817. var highestRes = [].slice.call(xmlDoc.querySelectorAll('Representation[frameRate]'))
  818. .sort(function (r1, r2) {
  819. var w1 = parseInt(r1.getAttribute('width')), w2 = parseInt(r2.getAttribute('width'));
  820. return w1 > w2 ? -1 : (w1 < w2 ? 1 : 0);
  821. })
  822. .find(function (repr) { return !!repr.querySelector('BaseURL'); });
  823.  
  824. if (highestRes) {
  825. var baseUrl = highestRes.querySelector('BaseURL').textContent.trim();
  826. return baseUrl.indexOf('//') !== -1 ? baseUrl : url.replace('DASHPlaylist.mpd', baseUrl);
  827. }
  828. } catch (err) {
  829. console.log(err);
  830. }
  831. }
  832. }
  833. },
  834. {
  835. name: "Rule34hentai",
  836. url: /rule34hentai\.net/,
  837. r: "/_thumbs/",
  838. s: "/_images/"
  839. },
  840. {
  841. name: "Rule34",
  842. url: /rule34\.xxx/,
  843. src: /\/(thumbnails|samples)\/(.*)\/(thumbnail|sample)_/i,
  844. r: /\/(thumbnails|samples)\/(.*)\/(thumbnail|sample)_(.*)\..*/i,
  845. s: ["/images/$2/$4.jpeg","/images/$2/$4.png","/images/$2/$4.jpg"]
  846. },
  847. {
  848. name: "Photosight",
  849. url: /photosight\.ru/,
  850. r: /(cdny\.de.*\/)t\//i,
  851. s: "$1x/"
  852. },
  853. {
  854. name: "Xiaohongshu",
  855. url: /xiaohongshu\.com/,
  856. ext: function(target) {
  857. if (target.className == 'change-pic') {
  858. var imgs=target.previousElementSibling.querySelectorAll('li'),i=0;
  859. for(i=0;i<imgs.length;i++){
  860. if(imgs[i].style.display!="none")
  861. return imgs[i].childNodes[0];
  862. }
  863. }
  864. return target;
  865. },
  866. r: [/\/w\/\d+\/(h\/\d+\/)?(q\/\d+\/)?/i, /.*\.xhscdn\.com.*\/(\w+)(!.*|$)/i],
  867. s: ["/w/1080/", "https://sns-img-bd.xhscdn.com/$1"]
  868. },
  869. {
  870. name: "Youtube",
  871. url: /youtube\.com/,
  872. ext: function(target) {
  873. if (target.tagName == "ytd-thumbnail" || target.id == "thumbnail-container") {
  874. return target.querySelector("img");
  875. }
  876. },
  877. getExtSrc: function() {
  878. let newsrc = "";
  879. if (this.id == "thumbnail-container" && this.children[0].hasAttribute("loaded")) {
  880. let img = this.querySelector('img');
  881. if (!img) return;
  882. newsrc = img.src;
  883. }
  884. return newsrc.replace(/\?.*$/i,"");
  885. },
  886. getImage: function(a, p) {
  887. var newsrc=this.src;
  888. if(p[2] && this.classList.contains('ytd-moving-thumbnail-renderer')){
  889. newsrc = p[2].querySelector("img").src;
  890. }
  891. if(!newsrc || newsrc.indexOf("i.ytimg.com") == -1) return;
  892. return newsrc.replace(/\?.*$/i,"");
  893. }
  894. },
  895. {
  896. name: "588ku",
  897. url: /588ku\.com/,
  898. r: /!\/fw.*/,
  899. s: ""
  900. },
  901. {
  902. name: "ibaotu",
  903. url: /ibaotu\.com/,
  904. ext: 'previous',
  905. r: "!fwc238",
  906. s: "!ww7002"
  907. },
  908. {
  909. name: "58pic",
  910. url: /58pic\.com/,
  911. ext: function(target){
  912. if(target.className=="no-login" && target.style.opacity==""){
  913. target.style.opacity=0.99;
  914. setTimeout(()=>{target.style.display="none";},1000);
  915. }
  916. return null;
  917. },
  918. r: /!.*/i,
  919. s: "!w1024"
  920. },
  921. {
  922. name: "gelbooru",
  923. url: /gelbooru\.com/,
  924. src: /(thumbnails|samples)\/(.*)\/(thumbnail|sample)_/i,
  925. r: /.*\/(thumbnails|samples)\/(.*)\/(thumbnail|sample)_(.*)\..*/i,
  926. s: ["https://img3.gelbooru.com/images/$2/$4.png","https://img3.gelbooru.com/images/$2/$4.jpg"]
  927. },
  928. {
  929. name: "donmai",
  930. url: /donmai\.us/,
  931. src: /(thumbnails|sample)\/(.*)\/(thumbnail|sample)_|\/\d+x\d+\//i,
  932. r: [/\/(thumbnails|sample)\/(.*)\/(thumbnail|sample)_(.*)/i,
  933. /\/\d+x\d+\//i
  934. ],
  935. s: ["/original/$2/$4","/original/"]
  936. },
  937. {
  938. name: "erosberry",
  939. url: /erosberry\.com/,
  940. r: /(\/\d+\/)tn_(\d+\.[^\/]+)$/i,
  941. s: "$1$2"
  942. },
  943. {
  944. name: "javdb",
  945. url: /javdb/,
  946. r: "/thumbs/",
  947. s: "/covers/"
  948. },
  949. {
  950. name: "javbus",
  951. url: /javbus\.|busjav\./,
  952. r: /\/thumbs?(\/\w+)\.jpg$/i,
  953. s: "/cover$1_b.jpg"
  954. },
  955. {
  956. name: "avmoo",
  957. url: /avmoo\./,
  958. r: "ps.jpg",
  959. s: "pl.jpg"
  960. },
  961. {
  962. name: "asiansister",
  963. url: /asiansister\.com/,
  964. r: "_t.",
  965. s: "."
  966. },
  967. {
  968. name: "jianshu",
  969. url: /jianshu\.com/,
  970. r: /(upload-images\.jianshu\.io\/.*)\?.*/i,
  971. s: "$1"
  972. },
  973. {
  974. name: "artstation",
  975. ext: 'next',
  976. url: /artstation\.com/,
  977. r: /\/(\d{14}\/)?smaller_square\//i,
  978. s: "/large/",
  979. xhr: {
  980. url: function(a, p) {
  981. if (a && a.href.match('/artwork/')) return a.href.replace('/artwork/', '/projects/') + '.json';
  982. },
  983. query: function(html) {
  984. let datas = JSON.parse(html);
  985. let urls = [];
  986. datas.assets.forEach(d => {
  987. urls.push(d.image_url)
  988. });
  989. return urls;
  990. }
  991. }
  992. },
  993. {
  994. name: "flickr",
  995. url: /flickr\.com/,
  996. ext: function(target){
  997. if(target.nodeName=="A" && target.className=="overlay" && target.parentNode && target.parentNode.parentNode && target.parentNode.parentNode.parentNode){
  998. return target.parentNode.parentNode.parentNode;
  999. }else if(target.nodeName=="DIV" && target.classList.contains("photo-notes-scrappy-view")){
  1000. return target.previousElementSibling.querySelector(".main-photo");
  1001. }else if(target.classList.contains("context-thumb")){
  1002. return target;
  1003. }
  1004. return null;
  1005. },
  1006. r: /_\w\./i,
  1007. s: "_c."
  1008. },
  1009. {
  1010. name: "wikiart",
  1011. url: /wikiart\.org/,
  1012. r: /!.*/i,
  1013. s: ''
  1014. },
  1015. {
  1016. name: "discuz",
  1017. r: [/(.+\/attachments?\/.+)\.thumb\.\w{2,5}$/i,
  1018. /((wp-content|moecdn\.org)\/uploads\/.*)\-\d+x\d+(-c)?/i,
  1019. /.*(?:url|src)=(https?:\/\/.*\.(?:jpg|jpeg|png|gif|bmp)).*/i,
  1020. /.*thumb\.php\?src=([^&]*).*/i],
  1021. s: '$1'
  1022. },
  1023. {
  1024. name: "weibo 视频",
  1025. url: /^https:\/\/(www\.|s\.|m\.)?weibo\.com/,
  1026. getExtSrc: function() {
  1027. if (this.classList.contains('hoverMask')) {
  1028. let video = this.parentNode.firstElementChild;
  1029. if (video && video.nodeName == 'VIDEO') return [video.poster, video.src];
  1030. }
  1031. },
  1032. video: /video$/
  1033. },
  1034. {
  1035. name: "weibo",
  1036. r: /(\.sinaimg\.(cn|com)\/)(?:bmiddle|orj360|mw\d+)/i,
  1037. s: '$1large'
  1038. },
  1039. {
  1040. name: "weibo2",
  1041. r: /(\.sinaimg\.(cn|com)\/)(?:square|thumbnail)/i,
  1042. s: '$1mw1024'
  1043. },
  1044. {
  1045. name: "sina head",
  1046. r: /(\.sinaimg\.(cn|com)\/\d+)\/50\//i,
  1047. s: '$1/180/'
  1048. },
  1049. {
  1050. name: "新浪相册",
  1051. src: /\.sinaimg\.(cn|com)\/thumb\d+\/\w+/i,
  1052. r: /thumb\d+/,
  1053. s: 'mw690'
  1054. },
  1055. {
  1056. name: "sina sports",
  1057. src: /k\.sinaimg\.cn\/n\//i,
  1058. r: /k\.sinaimg\.cn\/n\/(.*)\/(w\d+)?h\d+[^\/]+$/,
  1059. s: 'n.sinaimg.cn/$1'
  1060. },
  1061. {
  1062. name: "gravatar",
  1063. src: /gravatar\.com\/avatar\/|\/gravatar\//i,
  1064. r: /(avatar\/.*[\?&]s=).*/,
  1065. s: '$11920'
  1066. },
  1067. {
  1068. name: "ucServerAvatar",
  1069. src: /uc_server\/avatar\.php/i,
  1070. r: /(uc_server\/avatar\.php\?uid=\d+&size=).*/,
  1071. s: '$1big'
  1072. },
  1073. {
  1074. name: "md",
  1075. src: /\.md\./i,
  1076. r: /\.md(\.[^\.]+)$/i,
  1077. s: '$1'
  1078. },
  1079. {
  1080. name: "ytimg",
  1081. src: /i\.ytimg\.com/i,
  1082. exclude: /mqdefault_6s/i,
  1083. r: /\?.*$/i,
  1084. s: ''
  1085. },
  1086. {
  1087. name: "meituan",
  1088. url: /\.meituan\.net/i,
  1089. r: /\/avatar\/\w{2}/i,
  1090. s: '/avatar/o0'
  1091. },
  1092. {
  1093. name: "hdslb",
  1094. src: /hdslb\.com\//i,
  1095. r: /@.*/i,
  1096. s: ''
  1097. },
  1098. {
  1099. name: "coolapk",
  1100. url: /\.coolapk\.com\//i,
  1101. r: /\.s\.\w+$/i,
  1102. s: ''
  1103. },
  1104. {
  1105. name: "aicdn",
  1106. src: /\.aicdn\.com\//i,
  1107. r: /_fw\d+$/i,
  1108. s: ''
  1109. },
  1110. {
  1111. name: "duitang",
  1112. url: /duitang\.com\//i,
  1113. r: /.thumb.(\d+_)?\d*(_c)?\./i,
  1114. s: '.'
  1115. },
  1116. {
  1117. name: "imgur",
  1118. src: /imgur\.com\//i,
  1119. r: [/h(\.[^\/]+)$/i,/maxwidth=\d+/i,/b\./],
  1120. s: ["$1","maxwidth=99999","."]
  1121. },
  1122. {
  1123. name: "dmm",
  1124. src: /pics\.dmm\.co\.jp/i,
  1125. r: "ps.jpg",
  1126. s: "pl.jpg"
  1127. },
  1128. {
  1129. name: "whd",
  1130. src: /\/w\/\d+\/h\/\d+($|\/|\?)/i,
  1131. r: /\/w\/\d+\/h\/\d+/i,
  1132. s: ""
  1133. },
  1134. {
  1135. name: "百度图片、贴吧等",
  1136. src: /(hiphotos|imgsrc)\.baidu\.com/i,
  1137. r: /(hiphotos|imgsrc)\.baidu\.com\/(.+?)\/.+?([0-9a-f]{40})/i,
  1138. s: "$1.baidu.com/$2/pic/item/$3"
  1139. },
  1140. {
  1141. name: "GoogleContent",
  1142. src: /\/w\/\d+\/h\/\d+($|\/|\?)/i,
  1143. getImage:function(){
  1144. var $ = /^((?:(?:lh|gp|yt)\d+\.g(?:oogleuserconten|gph)|\d\.bp\.blogspo)t\.com\/)(?:([_-](?:[\w\-]{11}\/){4})[^\/]+(\/[^?#]+)?|([^=]+)).*/i.exec(this.src);
  1145. var newsrc= $ ? ('http://' + $[1] + ($[4] ? $[4] + '=' : $[2]) + 's2634' + ($[3] || '')) : '';
  1146. if(newsrc!=this.src)return newsrc;
  1147. }
  1148. },
  1149. {
  1150. name: "pixiv",
  1151. src: /pixiv\.net/i,
  1152. r: /(pixiv.net\/img\d+\/img\/.+\/\d+)_[ms]\.(\w{2,5})$/i,
  1153. s: "$1.$2"
  1154. },
  1155. {
  1156. name: "douban",
  1157. url: /douban\.com/i,
  1158. getImage:function(){
  1159. var $ = /(img\d+\.douban\.com\/)(?:(view\/)(?:photo|movie_poster_cover)\/(?!large)[^\/]+|(icon\/u(?=\d))|[sm](?=pic\/))(.*)/i.exec(this.src);
  1160. var newsrc= $ ? ('http://' + $[1] + ($[2] ? $[2] + 'photo/photo' : (($[3]||'') + 'l')) + $[4]) : '';
  1161. if(newsrc!=this.src)return newsrc;
  1162. }
  1163. },
  1164. {
  1165. name: "taobaocdn",
  1166. src: /(taobaocdn|alicdn)\.com/i,
  1167. r: [/.*((?:img\d\d\.taobaocdn|img(?:[^.]*\.?){1,2}?\.alicdn)\.com\/)(?:img\/|tps\/http:\/\/img\d\d+\.taobaocdn\.com\/)?((?:imgextra|bao\/uploaded)\/.+\.(?:jpe?g|png|gif|bmp))_.+\.jpg$/i,
  1168. /(.*\.alicdn\.com\/.*?)((.jpg|.png)(\.|_)\d+x\d+.*)\.jpg(_\.webp)?$/i,
  1169. /(.*\.alicdn\.com\/.*?)((\.|_)\d+x\d+.*|\.search|\.summ)\.jpg(_\.webp)?$/i],
  1170. s: ["http://$1$2",
  1171. "$1$3",
  1172. "$1.jpg"]
  1173. },
  1174. {
  1175. name: "taobao",
  1176. url: /item\.taobao\.com/i,
  1177. r: [/.*((?:img\d\d\.taobaocdn|img(?:[^.]*\.?){1,2}?\.alicdn)\.com\/)(?:img\/|tps\/http:\/\/img\d\d+\.taobaocdn\.com\/)?((?:imgextra|bao\/uploaded)\/.+\.(?:jpe?g|png|gif|bmp))_.+\.jpg$/i,
  1178. /(.*\.alicdn\.com\/.*?)((.jpg|.png)(\.|_)\d+x\d+.*)\.jpg(_\.webp)?$/i,
  1179. /(.*\.alicdn\.com\/.*?)((\.|_)\d+x\d+.*|\.search|\.summ)\.jpg(_\.webp)?$/i],
  1180. s: ["http://$1$2",
  1181. "$1$3",
  1182. "$1.jpg"],
  1183. getExtSrc:function(){
  1184. if(this.tagName=='A' && this.style.background){
  1185. return this.style.background.replace(/.*url\(['"](https?:)?(.*)['"]\).*/,"https:$2").replace(/_\d+x\d+\.\w+$/,"")
  1186. }
  1187. }
  1188. },
  1189. {
  1190. name: "yihaodianimg",
  1191. url: /yhd\.com/i,
  1192. src: /yihaodianimg\.com/i,
  1193. r: /(.*\.yihaodianimg\.com\/.*)_\d+x\d+\.jpg$/i,
  1194. s: "$1.jpg"
  1195. },
  1196. {
  1197. name: "jd",
  1198. url: /jd\.com/i,
  1199. src: /360buyimg\.com/i,
  1200. r: [/(.*360buyimg\.com\/)n\d\/.+?\_(.*)/i,
  1201. /(.*360buyimg\.com\/)n\d\/(.*)/i,
  1202. /(.*360buyimg\.com\/.*)s\d+x\d+_(.*)/i],
  1203. s: ["$1imgzone/$2","$1n0/$2","$1$2"]
  1204. },
  1205. {
  1206. name: "dangdang",
  1207. url: /dangdang\.com/i,
  1208. src: /ddimg\.cn/i,
  1209. r: /(.*ddimg.cn\/.*?)_[bw]_(\d+\.jpg$)/i,
  1210. s: "$1_e_$2"
  1211. },
  1212. {
  1213. name: "duokan",
  1214. url: /duokan\.com/i,
  1215. r: /(cover.read.duokan.com.*?\.jpg)!\w+$/i,
  1216. s: "$1"
  1217. },
  1218. {
  1219. name: "yyets",
  1220. url: /yyets\.com/i,
  1221. r: /^(res\.yyets\.com.*?\/ftp\/(?:attachment\/)?\d+\/\d+)\/[ms]_(.*)/i,
  1222. s: "http://$1/$2"
  1223. },
  1224. {
  1225. name: "mozilla",
  1226. url: /addons\.mozilla\.org/i,
  1227. r: "addons.cdn.mozilla.net/user-media/previews/thumbs/",
  1228. s: "/thumbs/full/"
  1229. },
  1230. {
  1231. name: "firefox",
  1232. url: /firefox\.net\.cn/i,
  1233. r: "www.firefox.net.cn/attachment/thumb/",
  1234. s: "www.firefox.net.cn/attachment/"
  1235. },
  1236. {
  1237. name: "crsky",
  1238. url: /\.crsky\.com/i,
  1239. r: /pic\.crsky\.com.*_s\.gif$/i,
  1240. s: "/_s././",
  1241. example: "http://www.crsky.com/soft/5357.html"
  1242. },
  1243. {
  1244. name: "zol",
  1245. url: /\.zol\.com/i,
  1246. r: /(\w+\.zol-img\.com\.cn\/product\/\d+)_\d+x\d+\/(.*\.jpg)/i,
  1247. s: "$1/$2",
  1248. example: "http://detail.zol.com.cn/240/239857/pic.shtml"
  1249. },
  1250. {
  1251. name: "yesky",
  1252. url: /\.yesky\.com/i,
  1253. r: /_\d+x\d+\.([a-z]+)$/i,
  1254. s: ".$1",
  1255. example: "http://game.yesky.com/tupian/165/37968665.shtml"
  1256. },
  1257. {
  1258. name:"巴哈姆特",
  1259. url:/^https:\/\/\w+\.gamer\.com\.tw/,
  1260. src: /bahamut\.com\.tw/,
  1261. r: "/S/",
  1262. s: "/B/"
  1263. },
  1264. {
  1265. name: "sgamer",
  1266. url: /\.sgamer\.com/i,
  1267. r: /\/s([^\.\/]+\.[a-z]+$)/i,
  1268. s: "/$1",
  1269. example: "http://dota2.sgamer.com/albums/201407/8263_330866.html"
  1270. },
  1271. {
  1272. name: "nhentai",
  1273. url: /nhentai\./i,
  1274. r: [/(cdn\..*\d+)t(\.[a-z]+)$/, /\/\/\w+(\..*\/)(\d+)t(\.[a-z]+)$/i],
  1275. s: ["$1$2","//i$1$2$3"],
  1276. example: "http://nhentai.net/g/113475/"
  1277. },
  1278. {
  1279. name: "GithubAvatars",
  1280. url: /github\.com/i,
  1281. r: /(avatars\d*\.githubusercontent\.com.*)\?.*$/i,
  1282. s: "$1",
  1283. example: "https://avatars2.githubusercontent.com/u/3233275/"
  1284. },
  1285. {
  1286. name: "ggpht",
  1287. src: /ggpht\.com/i,
  1288. r: /=s\d+.*/i,
  1289. s: "=s9999"
  1290. },
  1291. {
  1292. name: "kodansha",
  1293. url: /kodansha\.co\.jp/i,
  1294. src: /kodansha\.co\.jp/i,
  1295. r: 't_og_image_center',
  1296. s: 'c_limit'
  1297. },
  1298. {
  1299. name: "fanseven",
  1300. url: /fanseven\.com/i,
  1301. src: /fanseven\.com/i,
  1302. r: /w=\d+&h=\d+/i,
  1303. s: 'w=9999&h=9999'
  1304. },
  1305. {
  1306. name: "appstore",
  1307. url: /^https:\/\/apps\.apple\.com\//i,
  1308. getImage:function(){
  1309. if(this.parentNode.nodeName=="PICTURE"){
  1310. let source=this.parentNode.querySelector("source:last-of-type");
  1311. let maxSize=0;
  1312. let result="";
  1313. source.srcset.split(", ").forEach(srcset=>{
  1314. let srcArr=srcset.split(" ");
  1315. let curSize=parseInt(srcArr[1]);
  1316. if(curSize>maxSize){
  1317. maxSize=curSize;
  1318. result=srcArr[0];
  1319. }
  1320. });
  1321. return result;
  1322. }
  1323. return null;
  1324. }
  1325. },
  1326. {
  1327. name:"coomer.party & kemono.party",
  1328. url:/^https:\/\/(coomer|kemono)\.party\/.*\/post\//,
  1329. getImage:function(a){
  1330. if(a) return a.href;
  1331. }
  1332. },
  1333. {
  1334. name:"instagram",
  1335. url:/^https?:\/\/[^.]+\.instagram\.com/i,
  1336. ext: function(target) {
  1337. if(target && target.previousElementSibling){
  1338. let imgs=target.previousElementSibling.querySelectorAll("img");
  1339. if(imgs && imgs.length==1)return imgs[0];
  1340. }else if(target.tagName=='UL' && target.parentNode && target.parentNode.parentNode && target.parentNode.parentNode.tagName=='A'){
  1341. return target.parentNode.parentNode.querySelector('img');
  1342. }
  1343. },
  1344. xhr: {
  1345. url: function(a, p) {
  1346. if (!a) return;
  1347. const re = /\/(p|reel)\/([^/]{1,})/
  1348. const m = a.href.match(re);
  1349. if (m && a.querySelector('svg')) {
  1350. const shortcode = m[2];
  1351. const lower = 'abcdefghijklmnopqrstuvwxyz';
  1352. const upper = lower.toUpperCase();
  1353. const numbers = '0123456789';
  1354. const ig_alphabet = upper + lower + numbers + '-_';
  1355. const o = shortcode.replace(/\S/g, m => (ig_alphabet.indexOf(m) >>> 0).toString(2).padStart(6, '0'));
  1356. let mediaId = BigInt('0b' + o).toString(10);
  1357. return `https://www.instagram.com/api/v1/media/${mediaId}/info/`;
  1358. }
  1359. },
  1360. headers: {"X-IG-App-ID":"936619743392459"},
  1361. cacheNum: 20,
  1362. query: function(html) {
  1363. try {
  1364. const o = JSON.parse(html);
  1365. const items0 = o.items[0];
  1366. const images = items0.image_versions2;
  1367. const carousel = items0.carousel_media;
  1368. if (carousel) {
  1369. let gallery = [];
  1370. const caption = (items0.caption ? items0.caption.text : (items0.accessibility_caption ? items0.accessibility_caption : items0.user.full_name));
  1371. carousel.map(c => { gallery.push(c.video_versions ? c.video_versions[0].url : c.image_versions2.candidates[0].url); });
  1372. return {url: gallery, cap: caption};
  1373. } else if (images) {
  1374. const imagesUrl = images.candidates[0].url;
  1375. return imagesUrl;
  1376. }
  1377. } catch { }
  1378. }
  1379. }
  1380. },
  1381. {
  1382. name: "hentai-cosplays",
  1383. url: /^https:\/\/(.*\.)?(hentai\-cosplays|porn\-images\-xxx)\.com/,
  1384. r: /\/p=[\dx]+(\/\d+\.\w+)$/i,
  1385. s: '$1'
  1386. },
  1387. {
  1388. name:"beta.kemono.party",
  1389. url:/^https:\/\/(\w+\.)?kemono\.party\/.*\/post\//,
  1390. getImage:function(a){
  1391. if(a) return a.href;
  1392. }
  1393. },
  1394. {
  1395. name:"imdb",
  1396. url:/^https?:\/\/www\.imdb\.com/,
  1397. src: /media\-amazon/,
  1398. r: /@.*(\.\w)/i,
  1399. s: '@$1'
  1400. },
  1401. {
  1402. name:"nsfw.xxx",
  1403. url:/^https?:\/\/nsfw\.xxx/,
  1404. src: /thumbnails/,
  1405. xhr: {
  1406. url: function(a,p) {
  1407. if (a && a.className==='slider_init_href' && a.href && !this.nextElementSibling) {
  1408. return a.href;
  1409. }
  1410. },
  1411. query: '.sh-section__image>img',
  1412. }
  1413. },
  1414. {
  1415. name: "雪球",
  1416. url: /^https?:\/\/xueqiu\.com\//,
  1417. src: /^https?:\/\/xqimg\.imedao\.com\//i,
  1418. r: /!\d+(x\d+[a-z]?)?\.\w+$/,
  1419. s: ''
  1420. },
  1421. {
  1422. name: "小众论坛",
  1423. url: /^https?:\/\/meta\.appinn\.net/,
  1424. src: /meta\-cdn/,
  1425. r: /\/optimized\/(.*)_\d+_\d+x\d+(\.\w+)$/,
  1426. s: "/original/$1$2"
  1427. },
  1428. {
  1429. name: "诱惑福利图",
  1430. url: /www\.yhflt\.com/,
  1431. src: /imgs\.yhflt\.com/,
  1432. r: /imgs(\..*\/)q/,
  1433. s: "pic$1"
  1434. },
  1435. {
  1436. name: "Sankaku Complex",
  1437. url:/sankakucomplex\.com/,
  1438. src:/\/data\/preview\//,
  1439. xhr:{
  1440. url: "a",
  1441. query: "img#image"
  1442. }
  1443. },
  1444. {
  1445. name:"极简壁纸",
  1446. url:/https:\/\/bz\.zzzmh\.cn\//i,
  1447. getImage: function(a,p){
  1448. if(p&&p[1]&&p[1].classList.contains("img-box")){
  1449. let saveEle=p[1].querySelector("a");
  1450. if(saveEle) return saveEle.href;
  1451. }
  1452. }
  1453. },
  1454. {
  1455. name: "blogger",
  1456. src: /blogger\.googleusercontent\.com\/img/,
  1457. r: /\/[sw]\d+\/.*/,
  1458. s: "/s0"
  1459. },
  1460. {
  1461. name: "煎蛋",
  1462. url: /^https:\/\/jandan\.net\//,
  1463. r: [/\/(thumb\d+|mw\d+)\//, /!square/],
  1464. s: ["/large/", ""]
  1465. },
  1466. {
  1467. name:"辉夜白兔",
  1468. url:/47\.101\.137\.235/,
  1469. r:"thumb",
  1470. s:"regular"
  1471. },
  1472. {
  1473. name: "Civitai",
  1474. url: /^https:\/\/civitai\.com\//,
  1475. r: /\/width=\d+\//,
  1476. s: "/"
  1477. },
  1478. {
  1479. name: "網易雲音樂",
  1480. url: /^https:\/\/music\.163\.com\//,
  1481. getExtSrc:function() {
  1482. if (this.tagName === 'A' && this.className === "msk") {
  1483. return this.previousElementSibling.src.replace(/\?param=\d+y\d+/, "");
  1484. }
  1485. },
  1486. r: /\?param=\d+y\d+/,
  1487. s: ""
  1488. },
  1489. {
  1490. name: "Dlsite",
  1491. src: /^https:\/\/img\.dlsite\.jp\//,
  1492. r: /\/resize\/(.*)_\d+x\d+/,
  1493. s: "/modpub/$1"
  1494. },
  1495. {
  1496. name: "postype",
  1497. url: /^https:\/\/www\.postype\.com\//,
  1498. r: [/\/resize(\/.*\/)\d+x\d+x\d+\/\w+?\//, /\?w=.*/],
  1499. s: ["$1", ""]
  1500. },
  1501. {
  1502. name: "piccoma jp",
  1503. url: /^https:\/\/piccoma\.com\//,
  1504. r: [/(thumbnail|cover)_x\d/, /x\d$/],
  1505. s: ["cover_x3", "x3"],
  1506. getExtSrc: function() {
  1507. if (this.children[0] && this.children[0].nodeName === "IMG") {
  1508. return this.children[0].src.replace(/(thumbnail|cover)_x\d/, "cover_x3").replace(/x\d$/, "x3");
  1509. }
  1510. }
  1511. },
  1512. {
  1513. name: "bunkr",
  1514. url: /bunkr\.si/,
  1515. r: /\/thumbs(\/.*)png/,
  1516. s: "$1jpg"
  1517. },
  1518. {
  1519. name:"vk",
  1520. url:/vk\.com/,
  1521. xhr:{
  1522. url: function() {
  1523. if (this.classList.contains("photos_row")) {
  1524. return this.firstElementChild && this.firstElementChild.href;
  1525. }
  1526. },
  1527. query: function(html, doc) {
  1528. let r = doc.querySelector('meta[name="og:image"]');
  1529. if (!r) return;
  1530. r = r.getAttribute("value");
  1531. if (!r) return;
  1532. r = r.match(/\/([\w\-]+)\.(jpg|png)/);
  1533. if (!r) return;
  1534. r = r[1];
  1535. r = html.match(new RegExp(`"z_src":"([^"]*?${r}[^"]*?)","z_"`));
  1536. return r && r[1];
  1537. }
  1538. }
  1539. },
  1540. {
  1541. name: "sspai",
  1542. url: /^https?:\/\/sspai\.com\//,
  1543. r: /\?imageMogr.*/,
  1544. s: ""
  1545. },
  1546. {
  1547. name: "la-croix",
  1548. url: /^https?:\/\/www\.la\-croix\.com\//,
  1549. r: /\/\d+x\d+\//,
  1550. s: "/x/"
  1551. },
  1552. {
  1553. name:"e-hentai",
  1554. url:/^https?:\/\/(e\-|ex)hentai\.org\//i,
  1555. xhr: {
  1556. url: function(a, p) {
  1557. if (!a || !/blank\.gif$/.test(this.src)) return;
  1558. const re = /\/s\//i;
  1559. const m = a.href.match(re);
  1560. return m && a.href;
  1561. },
  1562. query: function(html, doc) {
  1563. let img = doc.querySelector("#img");
  1564. return img && img.src;
  1565. }
  1566. }
  1567. },
  1568. {
  1569. name:"turboimagehost",
  1570. url:/^https?:\/\/www\.turboimagehost\.com\//i,
  1571. xhr: {
  1572. url: ".bbc_link",
  1573. query: "#imageid"
  1574. }
  1575. },
  1576. {
  1577. name:"freepik",
  1578. url:/^https?:\/\/www\.freepik\.com\//i,
  1579. xhr: {
  1580. url: ".showcase__link",
  1581. query: "img[fetchpriority]"
  1582. }
  1583. },
  1584. {
  1585. name: "imgtraffic",
  1586. r: /^(https:\/\/imgtraffic\.com\/\d+)s\//,
  1587. s: "$1/"
  1588. },
  1589. {
  1590. name: "dailymail",
  1591. url: /^https:\/\/(www\.)?dailymail\.co\.uk\//i,
  1592. xhr: {
  1593. url: "a[href*='/article']",
  1594. query: "video,img.img-share[data-src]"
  1595. }
  1596. },
  1597. {
  1598. name: "zerochan",
  1599. url: /^https:\/\/(www\.)?zerochan\.net\//i,
  1600. xhr: {
  1601. url: "a.thumb",
  1602. query: "#large>a.preview"
  1603. }
  1604. },
  1605. {
  1606. name: "rutracker",
  1607. url: /^https:\/\/rutracker\.net\//i,
  1608. getImage: function(a) {
  1609. if (a && /fastpic\.ru/.test(a.href)) {
  1610. let matched = a.href.match(/\.(\w+)\.html(&|$)/);
  1611. return matched && this.src.replace("/thumb/", "/big/").replace(/\w+(\?.*|$)/, matched[1]);
  1612. }
  1613. }
  1614. },
  1615. {
  1616. name: "rule34.paheal",
  1617. url: /^https:\/\/rule34\.paheal\.net\//,
  1618. getImage: function(a, p) {
  1619. let result = this.src.match(/.*\/_thumbs\/((..)(..).*)\//);
  1620. if (result) {
  1621. result = `https://r34i.paheal-cdn.net/${result[2]}/${result[3]}/${result[1]}`;
  1622. if (p[1] && p[1].dataset.ext === "mp4") result = "video:" + result;
  1623. return result;
  1624. }
  1625. }
  1626. },
  1627. {
  1628. name: "amazon",
  1629. url: /^https?:\/\/www\.amazon\.com\//,
  1630. lazyAttr: "data-a-hires",
  1631. r: [/_AC_.*\./, /._SY\d+\_?/],
  1632. s: ["", ""]
  1633. }
  1634. ];