google.php 24 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117
  1. <?php
  2. // noJS but requires login/cookie token
  3. // https://www.google.com/search?q=asmr&tbm=isch&asearch=arc&async=arc_id:srp_a,ffilt:all,ve_name:MoreResultsContainer,use_ac:false,inf:0,_id:arc-srp_a,_pms:s,_fmt:pc
  4. class google{
  5. public function __construct(){
  6. include "lib/fuckhtml.php";
  7. $this->fuckhtml = new fuckhtml();
  8. include "lib/backend.php";
  9. $this->backend = new backend("google");
  10. $this->message = "Still working on a Google scraper that uses a headful browser. It will require Firefox + a webExtension running on a dedicated server. Waiting for my EDID adapter and we can get the show going. In the meantime, use the Google CSE/API or Yahoo JP/Startpage scrapers. They're all crippled in their own special ways but they're serviceable I guess.";
  11. }
  12. public function getfilters($page){
  13. $base = [
  14. "country" => [ // gl=<country> (image: cr=countryAF)
  15. "display" => "Country",
  16. "option" => [
  17. "any" => "Instance's country",
  18. "af" => "Afghanistan",
  19. "al" => "Albania",
  20. "dz" => "Algeria",
  21. "as" => "American Samoa",
  22. "ad" => "Andorra",
  23. "ao" => "Angola",
  24. "ai" => "Anguilla",
  25. "aq" => "Antarctica",
  26. "ag" => "Antigua and Barbuda",
  27. "ar" => "Argentina",
  28. "am" => "Armenia",
  29. "aw" => "Aruba",
  30. "au" => "Australia",
  31. "at" => "Austria",
  32. "az" => "Azerbaijan",
  33. "bs" => "Bahamas",
  34. "bh" => "Bahrain",
  35. "bd" => "Bangladesh",
  36. "bb" => "Barbados",
  37. "by" => "Belarus",
  38. "be" => "Belgium",
  39. "bz" => "Belize",
  40. "bj" => "Benin",
  41. "bm" => "Bermuda",
  42. "bt" => "Bhutan",
  43. "bo" => "Bolivia",
  44. "ba" => "Bosnia and Herzegovina",
  45. "bw" => "Botswana",
  46. "bv" => "Bouvet Island",
  47. "br" => "Brazil",
  48. "io" => "British Indian Ocean Territory",
  49. "bn" => "Brunei Darussalam",
  50. "bg" => "Bulgaria",
  51. "bf" => "Burkina Faso",
  52. "bi" => "Burundi",
  53. "kh" => "Cambodia",
  54. "cm" => "Cameroon",
  55. "ca" => "Canada",
  56. "cv" => "Cape Verde",
  57. "ky" => "Cayman Islands",
  58. "cf" => "Central African Republic",
  59. "td" => "Chad",
  60. "cl" => "Chile",
  61. "cn" => "China",
  62. "cx" => "Christmas Island",
  63. "cc" => "Cocos (Keeling) Islands",
  64. "co" => "Colombia",
  65. "km" => "Comoros",
  66. "cg" => "Congo",
  67. "cd" => "Congo, the Democratic Republic",
  68. "ck" => "Cook Islands",
  69. "cr" => "Costa Rica",
  70. "ci" => "Cote D'ivoire",
  71. "hr" => "Croatia",
  72. "cu" => "Cuba",
  73. "cy" => "Cyprus",
  74. "cz" => "Czech Republic",
  75. "dk" => "Denmark",
  76. "dj" => "Djibouti",
  77. "dm" => "Dominica",
  78. "do" => "Dominican Republic",
  79. "ec" => "Ecuador",
  80. "eg" => "Egypt",
  81. "sv" => "El Salvador",
  82. "gq" => "Equatorial Guinea",
  83. "er" => "Eritrea",
  84. "ee" => "Estonia",
  85. "et" => "Ethiopia",
  86. "fk" => "Falkland Islands (Malvinas)",
  87. "fo" => "Faroe Islands",
  88. "fj" => "Fiji",
  89. "fi" => "Finland",
  90. "fr" => "France",
  91. "gf" => "French Guiana",
  92. "pf" => "French Polynesia",
  93. "tf" => "French Southern Territories",
  94. "ga" => "Gabon",
  95. "gm" => "Gambia",
  96. "ge" => "Georgia",
  97. "de" => "Germany",
  98. "gh" => "Ghana",
  99. "gi" => "Gibraltar",
  100. "gr" => "Greece",
  101. "gl" => "Greenland",
  102. "gd" => "Grenada",
  103. "gp" => "Guadeloupe",
  104. "gu" => "Guam",
  105. "gt" => "Guatemala",
  106. "gn" => "Guinea",
  107. "gw" => "Guinea-Bissau",
  108. "gy" => "Guyana",
  109. "ht" => "Haiti",
  110. "hm" => "Heard Island and Mcdonald Islands",
  111. "va" => "Holy See (Vatican City State)",
  112. "hn" => "Honduras",
  113. "hk" => "Hong Kong",
  114. "hu" => "Hungary",
  115. "is" => "Iceland",
  116. "in" => "India",
  117. "id" => "Indonesia",
  118. "ir" => "Iran, Islamic Republic",
  119. "iq" => "Iraq",
  120. "ie" => "Ireland",
  121. "il" => "Israel",
  122. "it" => "Italy",
  123. "jm" => "Jamaica",
  124. "jp" => "Japan",
  125. "jo" => "Jordan",
  126. "kz" => "Kazakhstan",
  127. "ke" => "Kenya",
  128. "ki" => "Kiribati",
  129. "kp" => "Korea, Democratic People's Republic",
  130. "kr" => "Korea, Republic",
  131. "kw" => "Kuwait",
  132. "kg" => "Kyrgyzstan",
  133. "la" => "Lao People's Democratic Republic",
  134. "lv" => "Latvia",
  135. "lb" => "Lebanon",
  136. "ls" => "Lesotho",
  137. "lr" => "Liberia",
  138. "ly" => "Libyan Arab Jamahiriya",
  139. "li" => "Liechtenstein",
  140. "lt" => "Lithuania",
  141. "lu" => "Luxembourg",
  142. "mo" => "Macao",
  143. "mk" => "Macedonia, the Former Yugosalv Republic",
  144. "mg" => "Madagascar",
  145. "mw" => "Malawi",
  146. "my" => "Malaysia",
  147. "mv" => "Maldives",
  148. "ml" => "Mali",
  149. "mt" => "Malta",
  150. "mh" => "Marshall Islands",
  151. "mq" => "Martinique",
  152. "mr" => "Mauritania",
  153. "mu" => "Mauritius",
  154. "yt" => "Mayotte",
  155. "mx" => "Mexico",
  156. "fm" => "Micronesia, Federated States",
  157. "md" => "Moldova, Republic",
  158. "mc" => "Monaco",
  159. "mn" => "Mongolia",
  160. "ms" => "Montserrat",
  161. "ma" => "Morocco",
  162. "mz" => "Mozambique",
  163. "mm" => "Myanmar",
  164. "na" => "Namibia",
  165. "nr" => "Nauru",
  166. "np" => "Nepal",
  167. "nl" => "Netherlands",
  168. "an" => "Netherlands Antilles",
  169. "nc" => "New Caledonia",
  170. "nz" => "New Zealand",
  171. "ni" => "Nicaragua",
  172. "ne" => "Niger",
  173. "ng" => "Nigeria",
  174. "nu" => "Niue",
  175. "nf" => "Norfolk Island",
  176. "mp" => "Northern Mariana Islands",
  177. "no" => "Norway",
  178. "om" => "Oman",
  179. "pk" => "Pakistan",
  180. "pw" => "Palau",
  181. "ps" => "Palestinian Territory, Occupied",
  182. "pa" => "Panama",
  183. "pg" => "Papua New Guinea",
  184. "py" => "Paraguay",
  185. "pe" => "Peru",
  186. "ph" => "Philippines",
  187. "pn" => "Pitcairn",
  188. "pl" => "Poland",
  189. "pt" => "Portugal",
  190. "pr" => "Puerto Rico",
  191. "qa" => "Qatar",
  192. "re" => "Reunion",
  193. "ro" => "Romania",
  194. "ru" => "Russian Federation",
  195. "rw" => "Rwanda",
  196. "sh" => "Saint Helena",
  197. "kn" => "Saint Kitts and Nevis",
  198. "lc" => "Saint Lucia",
  199. "pm" => "Saint Pierre and Miquelon",
  200. "vc" => "Saint Vincent and the Grenadines",
  201. "ws" => "Samoa",
  202. "sm" => "San Marino",
  203. "st" => "Sao Tome and Principe",
  204. "sa" => "Saudi Arabia",
  205. "sn" => "Senegal",
  206. "cs" => "Serbia and Montenegro",
  207. "sc" => "Seychelles",
  208. "sl" => "Sierra Leone",
  209. "sg" => "Singapore",
  210. "sk" => "Slovakia",
  211. "si" => "Slovenia",
  212. "sb" => "Solomon Islands",
  213. "so" => "Somalia",
  214. "za" => "South Africa",
  215. "gs" => "South Georgia and the South Sandwich Islands",
  216. "es" => "Spain",
  217. "lk" => "Sri Lanka",
  218. "sd" => "Sudan",
  219. "sr" => "Suriname",
  220. "sj" => "Svalbard and Jan Mayen",
  221. "sz" => "Swaziland",
  222. "se" => "Sweden",
  223. "ch" => "Switzerland",
  224. "sy" => "Syrian Arab Republic",
  225. "tw" => "Taiwan, Province of China",
  226. "tj" => "Tajikistan",
  227. "tz" => "Tanzania, United Republic",
  228. "th" => "Thailand",
  229. "tl" => "Timor-Leste",
  230. "tg" => "Togo",
  231. "tk" => "Tokelau",
  232. "to" => "Tonga",
  233. "tt" => "Trinidad and Tobago",
  234. "tn" => "Tunisia",
  235. "tr" => "Turkey",
  236. "tm" => "Turkmenistan",
  237. "tc" => "Turks and Caicos Islands",
  238. "tv" => "Tuvalu",
  239. "ug" => "Uganda",
  240. "ua" => "Ukraine",
  241. "ae" => "United Arab Emirates",
  242. "uk" => "United Kingdom",
  243. "us" => "United States",
  244. "um" => "United States Minor Outlying Islands",
  245. "uy" => "Uruguay",
  246. "uz" => "Uzbekistan",
  247. "vu" => "Vanuatu",
  248. "ve" => "Venezuela",
  249. "vn" => "Viet Nam",
  250. "vg" => "Virgin Islands, British",
  251. "vi" => "Virgin Islands, U.S.",
  252. "wf" => "Wallis and Futuna",
  253. "eh" => "Western Sahara",
  254. "ye" => "Yemen",
  255. "zm" => "Zambia",
  256. "zw" => "Zimbabwe"
  257. ]
  258. ],
  259. "nsfw" => [
  260. "display" => "NSFW",
  261. "option" => [
  262. "yes" => "Yes", // safe=active
  263. "no" => "No" // safe=off
  264. ]
  265. ]
  266. ];
  267. switch($page){
  268. case "web":
  269. return array_merge(
  270. $base,
  271. [
  272. "lang" => [ // lr=<lang> (prefix lang with "lang_")
  273. "display" => "Language",
  274. "option" => [
  275. "any" => "Any language",
  276. "ar" => "Arabic",
  277. "bg" => "Bulgarian",
  278. "ca" => "Catalan",
  279. "cs" => "Czech",
  280. "da" => "Danish",
  281. "de" => "German",
  282. "el" => "Greek",
  283. "en" => "English",
  284. "es" => "Spanish",
  285. "et" => "Estonian",
  286. "fi" => "Finnish",
  287. "fr" => "French",
  288. "hr" => "Croatian",
  289. "hu" => "Hungarian",
  290. "id" => "Indonesian",
  291. "is" => "Icelandic",
  292. "it" => "Italian",
  293. "iw" => "Hebrew",
  294. "ja" => "Japanese",
  295. "ko" => "Korean",
  296. "lt" => "Lithuanian",
  297. "lv" => "Latvian",
  298. "nl" => "Dutch",
  299. "no" => "Norwegian",
  300. "pl" => "Polish",
  301. "pt" => "Portuguese",
  302. "ro" => "Romanian",
  303. "ru" => "Russian",
  304. "sk" => "Slovak",
  305. "sl" => "Slovenian",
  306. "sr" => "Serbian",
  307. "sv" => "Swedish",
  308. "tr" => "Turkish",
  309. "zh-CN" => "Chinese (Simplified)",
  310. "zh-TW" => "Chinese (Traditional)"
  311. ]
  312. ],
  313. "newer" => [ // tbs
  314. "display" => "Newer than",
  315. "option" => "_DATE"
  316. ],
  317. "older" => [
  318. "display" => "Older than",
  319. "option" => "_DATE"
  320. ],
  321. "spellcheck" => [
  322. "display" => "Spellcheck",
  323. "option" => [
  324. "yes" => "Yes",
  325. "no" => "No"
  326. ]
  327. ]
  328. ]
  329. );
  330. break;
  331. case "images":
  332. return array_merge(
  333. $base,
  334. [
  335. "time" => [ // tbs=qdr:<time>
  336. "display" => "Time posted",
  337. "option" => [
  338. "any" => "Any time",
  339. "d" => "Past 24 hours",
  340. "w" => "Past week",
  341. "m" => "Past month",
  342. "y" => "Past year"
  343. ]
  344. ],
  345. "size" => [ // imgsz
  346. "display" => "Size",
  347. "option" => [
  348. "any" => "Any size",
  349. "l" => "Large",
  350. "m" => "Medium",
  351. "i" => "Icon",
  352. "qsvga" => "Larger than 400x300",
  353. "vga" => "Larger than 640x480",
  354. "svga" => "Larger than 800x600",
  355. "xga" => "Larger than 1024x768",
  356. "2mp" => "Larger than 2MP",
  357. "4mp" => "Larger than 4MP",
  358. "6mp" => "Larger than 6MP",
  359. "8mp" => "Larger than 8MP",
  360. "10mp" => "Larger than 10MP",
  361. "12mp" => "Larger than 12MP",
  362. "15mp" => "Larger than 15MP",
  363. "20mp" => "Larger than 20MP",
  364. "40mp" => "Larger than 40MP",
  365. "70mp" => "Larger than 70MP"
  366. ]
  367. ],
  368. "ratio" => [ // imgar
  369. "display" => "Aspect ratio",
  370. "option" => [
  371. "any" => "Any ratio",
  372. "t|xt" => "Tall",
  373. "s" => "Square",
  374. "w" => "Wide",
  375. "xw" => "Panoramic"
  376. ]
  377. ],
  378. "color" => [ // imgc
  379. "display" => "Color",
  380. "option" => [
  381. "any" => "Any color",
  382. "color" => "Full color",
  383. "bnw" => "Black & white",
  384. "trans" => "Transparent",
  385. // from here, imgcolor
  386. "red" => "Red",
  387. "orange" => "Orange",
  388. "yellow" => "Yellow",
  389. "green" => "Green",
  390. "teal" => "Teal",
  391. "blue" => "Blue",
  392. "purple" => "Purple",
  393. "pink" => "Pink",
  394. "white" => "White",
  395. "gray" => "Gray",
  396. "black" => "Black",
  397. "brown" => "Brown"
  398. ]
  399. ],
  400. "type" => [ // tbs=itp:<type>
  401. "display" => "Type",
  402. "option" => [
  403. "any" => "Any type",
  404. "clipart" => "Clip Art",
  405. "lineart" => "Line Drawing",
  406. "animated" => "Animated"
  407. ]
  408. ],
  409. "format" => [ // as_filetype
  410. "display" => "Format",
  411. "option" => [
  412. "any" => "Any format",
  413. "jpg" => "JPG",
  414. "gif" => "GIF",
  415. "png" => "PNG",
  416. "bmp" => "BMP",
  417. "svg" => "SVG",
  418. "webp" => "WEBP",
  419. "ico" => "ICO",
  420. "craw" => "RAW"
  421. ]
  422. ],
  423. "rights" => [ // tbs=sur:<rights>
  424. "display" => "Usage rights",
  425. "option" => [
  426. "any" => "Any license",
  427. "cl" => "Creative Commons licenses",
  428. "ol" => "Commercial & other licenses"
  429. ]
  430. ]
  431. ]
  432. );
  433. break;
  434. case "videos":
  435. return array_merge(
  436. $base,
  437. [
  438. "newer" => [ // tbs
  439. "display" => "Newer than",
  440. "option" => "_DATE"
  441. ],
  442. "older" => [
  443. "display" => "Older than",
  444. "option" => "_DATE"
  445. ],
  446. "duration" => [
  447. "display" => "Duration",
  448. "option" => [
  449. "any" => "Any duration",
  450. "s" => "Short (0-4min)", // tbs=dur:s
  451. "m" => "Medium (4-20min)", // tbs=dur:m
  452. "l" => "Long (20+ min)" // tbs=dur:l
  453. ]
  454. ],
  455. "quality" => [
  456. "display" => "Quality",
  457. "option" => [
  458. "any" => "Any quality",
  459. "h" => "High quality" // tbs=hq:h
  460. ]
  461. ],
  462. "captions" => [
  463. "display" => "Captions",
  464. "option" => [
  465. "any" => "No preference",
  466. "yes" => "Closed captioned" // tbs=cc:1
  467. ]
  468. ]
  469. ]
  470. );
  471. break;
  472. case "news":
  473. return array_merge(
  474. $base,
  475. [
  476. "newer" => [ // tbs
  477. "display" => "Newer than",
  478. "option" => "_DATE"
  479. ],
  480. "older" => [
  481. "display" => "Older than",
  482. "option" => "_DATE"
  483. ],
  484. "sort" => [
  485. "display" => "Sort",
  486. "option" => [
  487. "relevance" => "Relevance",
  488. "date" => "Date" // sbd:1
  489. ]
  490. ]
  491. ]
  492. );
  493. break;
  494. }
  495. }
  496. private function get($proxy, $url, $get = []){
  497. $curlproc = curl_init();
  498. if($get !== []){
  499. $get = http_build_query($get);
  500. $url .= "?" . $get;
  501. }
  502. curl_setopt($curlproc, CURLOPT_URL, $url);
  503. curl_setopt($curlproc, CURLOPT_ENCODING, ""); // default encoding
  504. curl_setopt($curlproc, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
  505. curl_setopt($curlproc, CURLOPT_HTTPHEADER, [
  506. "User-Agent: " . config::USER_AGENT,
  507. "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
  508. "Accept-Language: en-US,en;q=0.5",
  509. "Accept-Encoding: gzip",
  510. "DNT: 1",
  511. "Connection: keep-alive",
  512. "Upgrade-Insecure-Requests: 1",
  513. "Sec-Fetch-Dest: document",
  514. "Sec-Fetch-Mode: navigate",
  515. "Sec-Fetch-Site: none",
  516. "Sec-Fetch-User: ?1",
  517. "Priority: u=1",
  518. "TE: trailers"
  519. ]);
  520. curl_setopt($curlproc, CURLOPT_RETURNTRANSFER, true);
  521. curl_setopt($curlproc, CURLOPT_SSL_VERIFYHOST, 2);
  522. curl_setopt($curlproc, CURLOPT_SSL_VERIFYPEER, true);
  523. curl_setopt($curlproc, CURLOPT_CONNECTTIMEOUT, 30);
  524. curl_setopt($curlproc, CURLOPT_TIMEOUT, 30);
  525. // follow redirects
  526. curl_setopt($curlproc, CURLOPT_FOLLOWLOCATION, true);
  527. $this->backend->assign_proxy($curlproc, $proxy);
  528. $data = curl_exec($curlproc);
  529. if(curl_errno($curlproc)){
  530. throw new Exception(curl_error($curlproc));
  531. }
  532. curl_close($curlproc);
  533. return $data;
  534. }
  535. public function web($get){
  536. throw new Exception($this->message);
  537. }
  538. public function image($get){
  539. throw new Exception($this->message);
  540. }
  541. public function video($get){
  542. throw new Exception($this->message);
  543. }
  544. public function news($get){
  545. throw new Exception($this->message);
  546. }
  547. private function scrape_dimg($html){
  548. // get images loaded through javascript
  549. $this->dimg = [];
  550. preg_match_all(
  551. '/function\(\){google\.ldi=({.*?});/',
  552. $html,
  553. $dimg
  554. );
  555. if(isset($dimg[1])){
  556. foreach($dimg[1] as $i){
  557. $tmp = json_decode($i, true);
  558. foreach($tmp as $key => $value){
  559. $this->dimg[$key] =
  560. $this->unshit_thumb(
  561. $value
  562. );
  563. }
  564. }
  565. }
  566. // get additional javascript base64 images
  567. preg_match_all(
  568. '/var s=\'(data:image\/[^\']+)\';var ii=\[((?:\'[^\']+\',?)+)\];/',
  569. $html,
  570. $dimg
  571. );
  572. if(isset($dimg[1])){
  573. for($i=0; $i<count($dimg[1]); $i++){
  574. $delims = explode(",", $dimg[2][$i]);
  575. $string =
  576. $this->fuckhtml
  577. ->parseJsString(
  578. $dimg[1][$i]
  579. );
  580. foreach($delims as $delim){
  581. $this->dimg[trim($delim, "'")] = $string;
  582. }
  583. }
  584. }
  585. }
  586. private function scrape_imagearr($html){
  587. // get image links arrays
  588. preg_match_all(
  589. '/\[[0-9]+,"([^"]+)",\["([^"]+)\",([0-9]+),([0-9]+)\],\["([^"]+)",([0-9]+),([0-9]+)\]/',
  590. $html,
  591. $image_arr
  592. );
  593. $this->image_arr = [];
  594. if(isset($image_arr[1])){
  595. for($i=0; $i<count($image_arr[1]); $i++){
  596. $original =
  597. $this->fuckhtml
  598. ->parseJsString(
  599. $image_arr[5][$i]
  600. );
  601. if(
  602. preg_match(
  603. '/^x-raw-image/',
  604. $original
  605. )
  606. ){
  607. // only add thumbnail, google doesnt have OG resolution
  608. $this->image_arr[$image_arr[1][$i]] = [
  609. [
  610. "url" =>
  611. $this->unshit_thumb(
  612. $this->fuckhtml
  613. ->parseJsString(
  614. $image_arr[2][$i]
  615. )
  616. ),
  617. "width" => (int)$image_arr[7][$i], // pass the OG image width & height
  618. "height" => (int)$image_arr[6][$i]
  619. ]
  620. ];
  621. continue;
  622. }
  623. $this->image_arr[$image_arr[1][$i]] =
  624. [
  625. [
  626. "url" => $original,
  627. "width" => (int)$image_arr[7][$i],
  628. "height" => (int)$image_arr[6][$i]
  629. ],
  630. [
  631. "url" =>
  632. $this->unshit_thumb(
  633. $this->fuckhtml
  634. ->parseJsString(
  635. $image_arr[2][$i]
  636. )
  637. ),
  638. "width" => (int)$image_arr[4][$i],
  639. "height" => (int)$image_arr[3][$i]
  640. ]
  641. ];
  642. }
  643. }
  644. }
  645. private function getdimg($dimg){
  646. return isset($this->dimg[$dimg]) ? $this->dimg[$dimg] : null;
  647. }
  648. private function unshit_thumb($url, $get_bigger_res = false){
  649. // https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQINE2vbnNLHXqoZr3RVsaEJFyOsj1_BiBnJch-e1nyz3oia7Aj5xVj
  650. // https://i.ytimg.com/vi/PZVIyA5ER3Y/mqdefault.jpg?sqp=-oaymwEFCJQBEFM&rs=AMzJL3nXeaCpdIar-ltNwl82Y82cIJfphA
  651. $parts = parse_url($url);
  652. if(
  653. isset($parts["host"]) &&
  654. preg_match(
  655. '/(?:encrypted-)?tbn.*\.gstatic\.com/',
  656. $parts["host"]
  657. )
  658. ){
  659. parse_str($parts["query"], $params);
  660. if(isset($params["q"])){
  661. if($get_bigger_res){
  662. // this method doesnt always work, but does work for wiki thumbnails
  663. return
  664. "https://" . $parts["host"] . "/images?q=tbn:" .
  665. $this->base64url_encode(
  666. substr(
  667. $this->base64url_decode(
  668. explode(
  669. ":",
  670. $params["q"])[1]
  671. ),
  672. 0,
  673. 29
  674. )
  675. );
  676. }else{
  677. return "https://" . $parts["host"] . "/images?q=" . $params["q"];
  678. }
  679. }
  680. }
  681. return $url;
  682. }
  683. private function parsestyles(){
  684. $styles = [];
  685. $style_div =
  686. $this->fuckhtml
  687. ->getElementsByTagName(
  688. "style"
  689. );
  690. $raw_styles = "";
  691. foreach($style_div as $style){
  692. $raw_styles .= $style["innerHTML"];
  693. }
  694. // filter out media/keyframe queries
  695. $raw_styles =
  696. preg_replace(
  697. '/@\s*(?!font-face)[^{]+\s*{[\S\s]+?}\s*}/',
  698. "",
  699. $raw_styles
  700. );
  701. // get styles
  702. preg_match_all(
  703. '/(.+?){([\S\s]*?)}/',
  704. $raw_styles,
  705. $matches
  706. );
  707. for($i=0; $i<count($matches[1]); $i++){
  708. // get style values
  709. preg_match_all(
  710. '/([^:;]+):([^;]*?(?:\([^)]+\)[^;]*?)?)(?:;|$)/',
  711. $matches[2][$i],
  712. $values_regex
  713. );
  714. $values = [];
  715. for($k=0; $k<count($values_regex[1]); $k++){
  716. $values[trim($values_regex[1][$k])] =
  717. strtolower(trim($values_regex[2][$k]));
  718. }
  719. $names = explode(",", $matches[1][$i]);
  720. // h1,h2,h3 will each get their own array index
  721. foreach($names as $name){
  722. $name = trim($name, "}\t\n\r\0\x0B");
  723. foreach($values as $key => $value){
  724. $styles[$name][$key] = $value;
  725. }
  726. }
  727. }
  728. foreach($styles as $key => $values){
  729. $styles[$key]["_c"] = count($values);
  730. }
  731. $this->styles = $styles;
  732. // get CSS colors
  733. $this->css_colors = [];
  734. if(isset($this->styles[":root"])){
  735. foreach($this->styles[":root"] as $key => $value){
  736. $this->css_colors[$value] = strtolower($key);
  737. }
  738. }
  739. }
  740. private function getstyle($styles){
  741. $styles["_c"] = count($styles);
  742. foreach($this->styles as $style_key => $style_values){
  743. if(count(array_intersect_assoc($style_values, $styles)) === $styles["_c"] + 1){
  744. $style_key =
  745. explode(" ", $style_key);
  746. $style_key = $style_key[count($style_key) - 1];
  747. return
  748. ltrim(
  749. str_replace(
  750. [".", "#"],
  751. " ",
  752. $style_key
  753. )
  754. );
  755. }
  756. }
  757. return false;
  758. }
  759. private function getcolorvar($color){
  760. if(isset($this->css_colors[$color])){
  761. return $this->css_colors[$color];
  762. }
  763. return null;
  764. }
  765. private function unshiturl($url, $return_size = false){
  766. // decode
  767. $url =
  768. $this->fuckhtml
  769. ->getTextContent(
  770. $url
  771. );
  772. $url_parts = parse_url($url);
  773. if(isset($url_parts["query"])){
  774. parse_str($url_parts["query"], $query);
  775. }else{
  776. $query = [];
  777. }
  778. if(
  779. !isset(
  780. $url_parts["host"]
  781. ) ||
  782. stripos($url_parts["host"], "google.") !== false
  783. ){
  784. // no host, we have a tracking url
  785. if(isset($query["imgurl"])){
  786. $url = $query["imgurl"];
  787. }
  788. elseif(isset($query["q"])){
  789. $url = $query["q"];
  790. }
  791. }
  792. // rewrite URLs to remove extra tracking parameters
  793. $domain = parse_url($url, PHP_URL_HOST);
  794. if(
  795. preg_match(
  796. '/wikipedia.org$/',
  797. $domain
  798. )
  799. ){
  800. // rewrite wikipedia mobile URLs to desktop
  801. $url =
  802. $this->replacedomain(
  803. $url,
  804. preg_replace(
  805. '/([a-z0-9]+)(\.m\.)/',
  806. '$1.',
  807. $domain
  808. )
  809. );
  810. }
  811. elseif(
  812. preg_match(
  813. '/imdb\.com$|youtube\.[^.]+$/',
  814. $domain
  815. )
  816. ){
  817. // rewrite imdb and youtube mobile URLs too
  818. $url =
  819. $this->replacedomain(
  820. $url,
  821. preg_replace(
  822. '/^m\./',
  823. "",
  824. $domain
  825. )
  826. );
  827. }
  828. elseif(
  829. preg_match(
  830. '/play\.google\.[^.]+$/',
  831. $domain
  832. )
  833. ){
  834. // remove referrers from play.google.com
  835. $u_query = parse_url($url, PHP_URL_QUERY);
  836. if($u_query !== null){
  837. parse_str($u_query, $u_query);
  838. if(isset($u_query["referrer"])){ unset($u_query["referrer"]); }
  839. if(isset($u_query["hl"])){ unset($u_query["hl"]); }
  840. if(isset($u_query["gl"])){ unset($u_query["gl"]); }
  841. $query = http_build_query($query);
  842. $url =
  843. str_replace(
  844. $u_query,
  845. $u_query,
  846. $url
  847. );
  848. }
  849. }
  850. elseif(
  851. preg_match(
  852. '/twitter\.com$/',
  853. $domain
  854. )
  855. ){
  856. // remove more referrers from twitter.com
  857. $u_query = parse_url($url, PHP_URL_QUERY);
  858. if($u_query !== null){
  859. parse_str($u_query, $u_query);
  860. if(isset($u_query["ref_src"])){ unset($u_query["ref_src"]); }
  861. $u_query = http_build_query($u_query);
  862. $url =
  863. str_replace(
  864. $oldquery,
  865. $u_query,
  866. $url
  867. );
  868. }
  869. }
  870. elseif(
  871. preg_match(
  872. '/maps\.google\.[^.]+/',
  873. $domain
  874. )
  875. ){
  876. if(stripos($url, "maps?") !== false){
  877. $u_query = parse_url($url, PHP_URL_QUERY);
  878. if($u_query !== null){
  879. parse_str($u_query, $u_query);
  880. if(isset($u_query["daddr"])){
  881. $url =
  882. "https://maps.google.com/maps?daddr=" .
  883. urlencode($u_query["daddr"]);
  884. }
  885. }
  886. }
  887. }
  888. if($return_size){
  889. return [
  890. "url" => $url,
  891. "ref" => isset($query["imgrefurl"]) ? $query["imgrefurl"] : null,
  892. "thumb_width" => isset($query["tbnw"]) ? (int)$query["tbnw"] : null,
  893. "thumb_height" => isset($query["tbnh"]) ? (int)$query["tbnh"] : null,
  894. "image_width" => isset($query["w"]) ? (int)$query["w"] : null,
  895. "image_height" => isset($query["h"]) ? (int)$query["h"] : null
  896. ];
  897. }
  898. return $url;
  899. }
  900. private function replacedomain($url, $domain){
  901. return
  902. preg_replace(
  903. '/(https?:\/\/)([^\/]+)/',
  904. '$1' . $domain,
  905. $url
  906. );
  907. }
  908. private function titledots($title){
  909. return trim($title, " .\t\n\r\0\x0B…");
  910. }
  911. private function hms2int($time){
  912. $parts = explode(":", $time, 3);
  913. $time = 0;
  914. if(count($parts) === 3){
  915. // hours
  916. $time = $time + ((int)$parts[0] * 3600);
  917. array_shift($parts);
  918. }
  919. if(count($parts) === 2){
  920. // minutes
  921. $time = $time + ((int)$parts[0] * 60);
  922. array_shift($parts);
  923. }
  924. // seconds
  925. $time = $time + (int)$parts[0];
  926. return $time;
  927. }
  928. function base64url_decode($data){
  929. $b64 = strtr($data, "-_", "+/");
  930. $pad = strlen($b64) % 4;
  931. if ($pad) $b64 .= str_repeat("=", 4 - $pad);
  932. return base64_decode($b64);
  933. }
  934. function base64url_encode($data){
  935. return rtrim(strtr(base64_encode($data), "+/", "-_"), "=");
  936. }
  937. private function detect_sorry(){
  938. $captcha_form =
  939. $this->fuckhtml
  940. ->getElementById(
  941. "captcha-form",
  942. "form"
  943. );
  944. if($captcha_form !== false){
  945. throw new Exception("Google returned a captcha");
  946. }
  947. }
  948. }