| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229 |
- <?php
- class baidu{
-
- public function __construct(){
-
- include "lib/backend.php";
- $this->backend = new backend("baidu");
-
- include "lib/fuckhtml.php";
- $this->fuckhtml = new fuckhtml();
-
- $this->handles = [];
- $this->proc = null;
- $this->handle_category = null;
- $this->handle_increment = 0;
- $this->sublink_increment = 0;
-
- $this->cookie = null;
- }
-
- public function getfilters($page){
-
- switch($page){
-
- case "web":
- return
- [
- "newer" => [
- "display" => "Newer than",
- "option" => "_DATE"
- ],
- "older" => [
- "display" => "Older than",
- "option" => "_DATE"
- ]
- ];
- break;
-
- case "images":
- return
- [
- "sort" => [
- "display" => "Sort",
- "option" => [
- "relevance" => "Relevance", // no param
- "latest" => "Latest", // &latest=1
- "hot" => "Hot" // &hot=1
- ]
- ],
- "size" => [
- "display" => "Size",
- "option" => [
- "any" => "Any size",
- "7" => "Extra large (1080px+)", // &z=7
- "6" => "Large (600px~1080px)", // &z=6
- "5" => "Medium (300px~600px)", // &z=5
- "4" => "Small (1px~300px)" // &z=4
- ]
- ],
- "ratio" => [
- "display" => "Ratio",
- "option" => [
- "any" => "Any ratio",
- "1" => "Tall vertical", // &imgratio=1
- "2" => "Vertical", // &imgratio=2
- "3" => "Square", // &imgratio=3
- "4" => "Horizontal", // &imgratio=4
- "5" => "Wide horizontal" // &imgratio=5
- ]
- ],
- "format" => [
- "display" => "Format",
- "option" => [
- "any" => "Any format",
- "3" => "JPG", // &imgformat=3
- "5" => "JPEG", // &imgformat=5
- "4" => "PNG", // &imgformat=4
- "2" => "BMP", // &imgformat=2
- "6" => "GIF (Animated)" // &imgformat=6
- ]
- ],
- "color" => [
- "display" => "Color",
- "option" => [
- "any" => "Any color",
- "1024" => "White", // &ic=1024
- "2048" => "Black & White",
- "512" => "Black",
- "64" => "Magenta",
- "16" => "Blue",
- "1" => "Red",
- "2" => "Yellow",
- "32" => "Purple",
- "4" => "Green",
- "8" => "Teal",
- "256" => "Orange",
- "128" => "Brown"
- ]
- ],
- "type" => [
- "display" => "Type",
- "option" => [
- "any" => "Any type",
- "hd" => "HD", // &hd=1
- "isImgSet" => "Photo album", // &isImgSet=1
- "copyright" => "Copyright" // ©right=1
- ]
- ]
- ];
- break;
-
- case "videos":
- return [];
- break;
-
- case "news":
- return [
- "category" => [
- "display" => "Category",
- "option" => [
- "any" => "All news",
- "media" => "Media websites", // &medium=1
- "baijiahao" => "Baidu Baijiahao" // &medium=2
- ]
- ]
- ];
- break;
- }
- }
-
- private function get($proxy, $url, $get = [], $referer = false){
-
- $curlproc = curl_init();
-
- if($get !== []){
- $get = http_build_query($get);
- $url .= "?" . $get;
- }
-
- $cookies_tmp = [];
- curl_setopt($curlproc, CURLOPT_HEADERFUNCTION, function($curlproc, $header) use (&$cookies_tmp){
-
- $length = strlen($header);
-
- $header = explode(":", $header, 2);
-
- if(trim(strtolower($header[0])) == "set-cookie"){
-
- $cookie_tmp = explode("=", trim($header[1]), 2);
-
- $cookies_tmp[trim($cookie_tmp[0])] =
- explode(";", $cookie_tmp[1], 2)[0];
- }
-
- return $length;
- });
-
- curl_setopt($curlproc, CURLOPT_URL, $url);
-
- curl_setopt($curlproc, CURLOPT_ENCODING, ""); // default encoding
-
- if($referer === false){
- if($this->cookie === null){
-
- curl_setopt($curlproc, CURLOPT_HTTPHEADER,
- ["User-Agent: " . config::USER_AGENT,
- "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
- "Accept-Language: en-US,en;q=0.5",
- "Accept-Encoding: gzip, deflate, br, zstd",
- "DNT: 1",
- "Sec-GPC: 1",
- "Connection: keep-alive",
- "Upgrade-Insecure-Requests: 1",
- "Sec-Fetch-Dest: document",
- "Sec-Fetch-Mode: navigate",
- "Sec-Fetch-Site: cross-site",
- "Priority: u=0, i"]
- );
- }else{
-
- curl_setopt($curlproc, CURLOPT_HTTPHEADER,
- ["User-Agent: " . config::USER_AGENT,
- "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
- "Accept-Language: en-US,en;q=0.5",
- "Accept-Encoding: gzip, deflate, br, zstd",
- "DNT: 1",
- "Sec-GPC: 1",
- "Connection: keep-alive",
- "Cookie: {$this->cookie}",
- "Upgrade-Insecure-Requests: 1",
- "Sec-Fetch-Dest: document",
- "Sec-Fetch-Mode: navigate",
- "Sec-Fetch-Site: cross-site",
- "Priority: u=0, i"]
- );
- }
- }else{
-
- if($this->cookie === null){
-
- curl_setopt($curlproc, CURLOPT_HTTPHEADER,
- ["User-Agent: " . config::USER_AGENT,
- "Accept: application/json, text/plain, */*",
- "Accept-Language: en-US,en;q=0.5",
- "Accept-Encoding: gzip, deflate, br, zstd",
- "Referer: {$referer}",
- "DNT: 1",
- "Sec-GPC: 1",
- "Connection: keep-alive",
- "Upgrade-Insecure-Requests: 1",
- "Sec-Fetch-Dest: empty",
- "Sec-Fetch-Mode: cors",
- "Sec-Fetch-Site: same-origin"]
- );
- }else{
-
- curl_setopt($curlproc, CURLOPT_HTTPHEADER,
- ["User-Agent: " . config::USER_AGENT,
- "Accept: application/json, text/plain, */*",
- "Accept-Language: en-US,en;q=0.5",
- "Accept-Encoding: gzip, deflate, br, zstd",
- "Referer: {$referer}",
- "DNT: 1",
- "Sec-GPC: 1",
- "Connection: keep-alive",
- "Cookie: {$this->cookie}",
- "Upgrade-Insecure-Requests: 1",
- "Sec-Fetch-Dest: empty",
- "Sec-Fetch-Mode: cors",
- "Sec-Fetch-Site: same-origin"]
- );
- }
- }
-
- curl_setopt($curlproc, CURLOPT_RETURNTRANSFER, true);
- curl_setopt($curlproc, CURLOPT_SSL_VERIFYHOST, 2);
- curl_setopt($curlproc, CURLOPT_SSL_VERIFYPEER, true);
- curl_setopt($curlproc, CURLOPT_CONNECTTIMEOUT, 30);
- curl_setopt($curlproc, CURLOPT_TIMEOUT, 30);
-
- $this->backend->assign_proxy($curlproc, $proxy);
-
- $data = curl_exec($curlproc);
-
- if(curl_errno($curlproc)){
-
- throw new Exception(curl_error($curlproc));
- }
-
- // store cookie
- if(strlen($this->cookie) !== 0){
-
- $this->cookie .= "; ";
- }
-
- foreach($cookies_tmp as $cookie_name => $cookie_value){
-
- $this->cookie .= $cookie_name . "=" . $cookie_value . "; ";
- }
-
- $this->cookie = rtrim($this->cookie, " ;");
-
- curl_close($curlproc);
- return $data;
- }
-
- private function redirect_add_url($proxy, $url){
-
- if(
- preg_match(
- '/^https?:\/\/(?:www\.)?baidu\.com\/link\?/',
- $url
- ) === 0
- ){
-
- // not a baidu redirect
- return;
- }
-
- $curlproc = curl_init();
-
- curl_setopt($curlproc, CURLOPT_URL, $url);
-
- curl_setopt($curlproc, CURLOPT_ENCODING, ""); // default encoding
- curl_setopt($curlproc, CURLOPT_HTTPHEADER,
- ["User-Agent: " . config::USER_AGENT,
- "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
- "Accept-Language: en-US,en;q=0.5",
- "Accept-Encoding: gzip, deflate, br, zstd",
- "DNT: 1",
- "Sec-GPC: 1",
- "Connection: keep-alive",
- "Upgrade-Insecure-Requests: 1",
- "Sec-Fetch-Dest: document",
- "Sec-Fetch-Mode: navigate",
- "Sec-Fetch-Site: none",
- "Sec-Fetch-User: ?1",
- "Priority: u=0, i"]
- );
-
- curl_setopt($curlproc, CURLOPT_RETURNTRANSFER, true);
- curl_setopt($curlproc, CURLOPT_SSL_VERIFYHOST, 2);
- curl_setopt($curlproc, CURLOPT_SSL_VERIFYPEER, true);
- curl_setopt($curlproc, CURLOPT_CONNECTTIMEOUT, 30);
- curl_setopt($curlproc, CURLOPT_TIMEOUT, 30);
-
- curl_setopt($curlproc, CURLOPT_HEADER, true);
- curl_setopt($curlproc, CURLOPT_NOBODY, true);
-
- $this->backend->assign_proxy($curlproc, $proxy);
-
- curl_multi_add_handle($this->proc, $curlproc);
- $this->handles[$this->handle_category][$this->handle_increment][$this->sublink_increment] = $curlproc;
- }
-
- private function resolve_urls($proxy, &$collection, $categories){
-
- $this->proc = curl_multi_init();
- curl_multi_select($this->proc);
-
- foreach($categories as $category){
-
- $this->sublink_increment = 0;
- $this->handle_increment = 0;
- $this->handle_category = $category;
-
- foreach($collection[$category] as $item){
-
- $this->sublink_increment = 0;
- $this->redirect_add_url($proxy, $item["url"]);
-
- if(isset($item["sublink"])){
-
- foreach($item["sublink"] as $sublink){
-
- $this->sublink_increment++;
- $this->redirect_add_url($proxy, $sublink["url"]);
- }
- }
-
- $this->handle_increment++;
- }
- }
-
- do{
- $status = curl_multi_exec($this->proc, $active);
-
- }while($active && $status == CURLM_OK);
-
- //
- // if we reach this, we're done downloading garbage
- //
-
- foreach($this->handles as $category => $v){
-
- foreach($v as $index => $data){
-
- foreach($this->handles[$category][$index] as $sublinkindex => $handle){
-
- preg_match(
- '/location: ?(.*)$/im',
- curl_multi_getcontent($handle),
- $location
- );
-
- if(isset($location[1])){
-
- if($sublinkindex === 0){
-
- $collection[$category][$index]["url"] = trim($location[1]);
- }else{
-
- $collection[$category][$index]["sublink"][$sublinkindex - 1]["url"] = trim($location[1]);
- }
- }
-
- curl_multi_remove_handle($this->proc, $handle);
- curl_close($handle);
- }
- }
- }
-
- curl_multi_close($this->proc);
- }
-
- private function resolve_images($proxy, &$data){
-
- // get the image viewer that contains all of the images direct URLs
- // for some reason, getting the second image's url in the set
- // doesnt trigger the captcha
-
- if(
- !isset($data["image"][1]["url"]) ||
- preg_match(
- '/^https:\/\/image\.baidu\.com\/search\/detail/',
- $data["image"][1]["url"]
- ) === 0
- ){
-
- // we have an already resolved image link, do nothing
- return;
- }
-
- try{
-
- $html =
- $this->get(
- $proxy,
- $data["image"][1]["url"],
- []
- );
- }catch(Exception $error){
-
- // fallback to the limited dataset we have
- return;
- }
-
- $this->fuckhtml->load($html);
-
- $script =
- $this->fuckhtml
- ->getElementById(
- "image-detail-data",
- "script"
- );
-
- if($script){
-
- $json =
- json_decode(
- $script["innerHTML"],
- true
- );
-
- if(
- !isset($json["data"]["images"]) ||
- count($json["data"]["images"]) === 0
- ){
-
- // do nothing
- return;
- }
-
- //
- // Discard all previously scraped images and use data
- // from the newly downloaded image carousel
- // the imageset !!should!! be the same
- //
- $data["image"] = [];
-
- foreach($json["data"]["images"] as $image){
-
- parse_str(parse_url($image["thumburl"], PHP_URL_QUERY), $thumb_size);
-
- $data["image"][] = [
- "title" =>
- $this->fuckhtml
- ->getTextContent(
- $image["titleShow"]
- ),
- "source" => [
- [
- "url" => $image["objurl"],
- "width" => (int)$image["width"],
- "height" => (int)$image["height"]
- ],
- [ // thumbnail
- "url" => $image["thumburl"],
- "width" => (int)$thumb_size["w"],
- "height" => (int)$thumb_size["h"]
- ]
- ],
- "url" => $image["fromUrl"]
- ];
- }
- }
- }
-
- public function web($get){
-
- if($get["npt"]){
-
- [$json, $proxy] = $this->backend->get($get["npt"], "web");
-
- $json = json_decode($json, true);
- $this->cookie = $json["cookie"];
- $npt_data = $json["req"];
-
- $npt_data["pn"] = $npt_data["pn"] + 20;
-
- try{
-
- $html = $this->get(
- $proxy,
- "https://www.baidu.com/s",
- $npt_data
- );
- }catch(Exception $error){
-
- throw new Exception("Failed to fetch search page");
- }
-
- }else{
-
- //
- // Get authentication token
- //
- $proxy = $this->backend->get_ip();
-
- // running this will give us shit in $this->cookie
- // @TODO probably not needed? I get blocked anyways ffs
- //$this->get($proxy, "https://www.baidu.com", []);
-
- $npt_data = [
- "wd" => $get["s"],
- "rn" => 20
- ];
-
- // &gpc=stf%3D0%2C1752638400|stftype%3D2
- if(
- $get["older"] !== false ||
- $get["newer"] !== false
- ){
-
- if($get["older"] === false){
-
- $get["older"] = 0;
- }
-
- $npt_data["gpc"] = "stf={$get["older"]},{$get["newer"]}|stftype=2";
- }
-
- try{
-
- $html = $this->get(
- $proxy,
- "https://www.baidu.com/s",
- $npt_data
- );
- }catch(Exception $error){
-
- throw new Exception("Failed to fetch search page");
- }
-
- $npt_data["pn"] = 0;
- }
-
- return $this->parse_search($proxy, "web", $npt_data, $html);
- }
-
- private function parse_search($proxy, $pagetype, $npt_data, $html){
-
- // @HACK
- // remove newlines from the html, cause it fucks with fuckhtml
- $html = str_replace(["\n", "\r"], "", $html);
-
- $out = [
- "status" => "ok",
- "spelling" => [
- "type" => "no_correction",
- "using" => null,
- "correction" => null
- ],
- "npt" => null,
- "answer" => [],
- "web" => [],
- "image" => [],
- "video" => [],
- "news" => [],
- "related" => []
- ];
-
- $this->fuckhtml->load($html);
-
- $this->detect_ass();
-
- $datafields =
- $this->fuckhtml
- ->getElementsByAttributeName(
- "id",
- "div"
- );
-
- //
- // Get next page
- //
- $npt =
- $this->fuckhtml
- ->getElementsByClassName(
- "n",
- "a"
- );
-
- if(count($npt) !== 0){
-
- $out["npt"] =
- $this->backend->store(
- json_encode([
- "req" => $npt_data,
- "cookie" => $this->cookie
- ]),
- $pagetype,
- $proxy
- );
- }
-
- //
- // Get related searches
- //
- $related_container =
- $this->fuckhtml
- ->getElementById(
- "rs_new",
- $datafields
- );
-
- if($related_container){
-
- $this->fuckhtml->load($related_container);
-
- $as =
- $this->fuckhtml
- ->getElementsByClassName(
- "c-color-link",
- "a"
- );
-
- foreach($as as $a){
-
- $text =
- explode(
- ">",
- $this->fuckhtml
- ->getTextContent(
- $a
- ),
- 2
- );
-
- $out["related"][] = $text[count($text) - 1];
- }
- }
-
- foreach($datafields as $datafield){
-
- if(
- !isset($datafield["attributes"]["id"]) ||
- preg_match(
- '/^[0-9]+$/',
- $datafield["attributes"]["id"]
- ) === 0
- ){
-
- // not a search result
- continue;
- }
-
- $this->fuckhtml->load($datafield);
- $div =
- $this->fuckhtml
- ->getElementsByTagName(
- "div"
- );
-
- //
- // Don't parse as a search result if it's a card
- //
- $card =
- $this->fuckhtml
- ->getElementsByClassName(
- "cosc-card",
- $div
- );
-
- if(count($card) !== 0){
-
- //
- // Parse chinese youtube shorts
- //
- $ytshorts_probe =
- $this->fuckhtml
- ->getElementsByClassName(
- "tts-b-item",
- $div
- );
-
- if(count($ytshorts_probe) !== 0){
-
- $videos =
- $this->fuckhtml
- ->getElementsByAttributeValue(
- "data-show",
- "list",
- $div
- );
-
- foreach($videos as $video){
-
- $this->fuckhtml->load($video);
-
- $title =
- $this->fuckhtml
- ->getElementsByClassName(
- "cosc-title-slot",
- "span"
- );
-
- if(count($title) === 0){
-
- continue;
- }
-
- $url =
- $this->fuckhtml
- ->getElementsByTagName(
- "a"
- );
-
- if(count($url) === 0){
-
- continue;
- }
-
- $image =
- $this->fuckhtml
- ->getElementsByClassName(
- "cos-image-body",
- "img"
- );
-
- if(count($image) === 0){
-
- $image = [
- "ratio" => null,
- "url" => null
- ];
- }else{
-
- $image = [
- "ratio" => "1:1",
- "url" =>
- $this->fuckhtml
- ->getTextContent(
- $image[0]["attributes"]["src"]
- )
- ];
- }
-
- // get duration
- $divs =
- $this->fuckhtml
- ->getElementsByAttributeName(
- "class",
- "div"
- );
-
- $duration = null;
- foreach($divs as $probe){
-
- if(strpos($probe["attributes"]["class"], "tag-bottom-right") !== false){
-
- $duration =
- $this->hms2int(
- $this->fuckhtml
- ->getTextContent(
- $probe
- )
- );
- break;
- }
- }
-
- $out["video"][] = [
- "title" =>
- $this->fuckhtml
- ->getTextContent(
- $title[0]
- ),
- "description" => null,
- "date" => null,
- "duration" => $duration,
- "views" => null,
- "thumb" => $image,
- "url" =>
- $this->fuckhtml
- ->getTextContent(
- $url[0]["attributes"]["href"]
- )
- ];
- }
- }
-
- //
- // Parse image carousel
- //
- $is_image_carousel = false;
- foreach($div as $d){
-
- if(
- isset($d["attributes"]["class"]) &&
- strpos($d["attributes"]["class"], "image-container") !== false
- ){
-
- $is_image_carousel = true;
- break;
- }
- }
-
- if($is_image_carousel){
-
- preg_match(
- '/<!--s-data:([\S\s]*)-->/U',
- $datafield["innerHTML"],
- $matches
- );
-
- if(isset($matches[1])){
-
- // weird behavior with the smaller image carousel where --cos* CSS variables are escaped wrong
- $json =
- $this->fuckhtml
- ->parseJsObject(
- str_replace(
- "-\-",
- "--",
- $matches[1]
- )
- );
-
- if(
- $json !== null &&
- isset($json["imageList"][0]["images"])
- ){
-
- // parse image carousel
- foreach($json["imageList"][0]["images"] as $image){
-
- parse_str(parse_url($image["thumburl"], PHP_URL_QUERY), $thumb_size);
-
- $out["image"][] = [
- "title" => "image",
- "source" => [
- [
- "url" => $image["objurl"],
- "width" => (int)$image["width"],
- "height" => (int)$image["height"]
- ],
- [ // thumbnail
- "url" => $image["thumburl"],
- "width" => (int)$thumb_size["w"],
- "height" => (int)$thumb_size["h"]
- ]
- ],
- "url" => $image["jumpUrl"]
- ];
- }
- }
- }
- }
- continue;
- }
-
- if(!isset($datafield["attributes"]["mu"])){
-
- // dont scrape if we dont have the direct link
- continue;
- }
-
- // class:FYB_RD -> News garbage, IGNORE
-
- $result =
- $this->fuckhtml
- ->getElementsByClassName(
- "result",
- [$datafield]
- );
-
- if(count($result) !== 0){
-
- //
- // Parse normal search result
- //
-
- $title =
- $this->fuckhtml
- ->getElementsByClassName(
- "sc-link",
- "a"
- );
-
- if(count($title) === 0){
-
- // should not happen
- continue;
- }
-
- $title =
- $this->titledots(
- $this->fuckhtml
- ->getTextContent(
- $title[0]
- )
- );
-
- $description =
- $this->fuckhtml
- ->getElementsByClassName(
- "c-color",
- $div
- );
-
- if(count($description) !== 0){
-
- $this->fuckhtml->load($description[0]);
-
- $description =
- $this->fuckhtml
- ->getElementsByAttributeName(
- "class",
- "span"
- );
-
- $found_desc = false;
- foreach($description as $desc){
-
- if(stripos($desc["attributes"]["class"], "summary-text") !== false){
-
- $found_desc = true;
- $description =
- $this->titledots(
- $this->fuckhtml
- ->getTextContent(
- $desc
- )
- );
- break;
- }
- }
-
- if($found_desc === false){
-
- $description = null;
- }
-
- $this->fuckhtml->load($datafield);
- }else{
-
- $description = null;
- }
-
- // parse date
- $date_probe =
- $this->fuckhtml
- ->getElementsByClassName(
- "cos-color-text-minor",
- "span"
- );
-
- if(count($date_probe) !== 0){
-
- $date =
- $this->parse_time(
- $this->fuckhtml
- ->getTextContent(
- $date_probe[0]
- )
- );
- }else{
-
- $date = null;
- }
-
- // parse image
- $img =
- $this->fuckhtml
- ->getElementsByTagName(
- "img"
- );
-
- if(count($img) !== 0){
-
- $image = [
- "ratio" => "16:9",
- "url" =>
- $this->unfuckthumb(
- $this->fuckhtml
- ->getTextContent(
- $img[0]["attributes"]["src"]
- )
- )
- ];
- }else{
-
- $image = [
- "ratio" => null,
- "url" => null
- ];
- }
-
- // get page type
- $pagetype_probe =
- $this->fuckhtml
- ->getElementsByTagName(
- "b"
- );
-
- $pagetype = "web";
- foreach($pagetype_probe as $probe){
-
- $pagetype =
- strtolower(
- trim(
- $this->fuckhtml
- ->getTextContent(
- $probe
- ),
- " 【】"
- )
- );
- }
-
- // get extra links
- $sublinks = [];
-
- foreach($div as $d){
-
- if(
- isset($d["attributes"]["class"]) &&
- strpos($d["attributes"]["class"], "exta-link") !== false
- ){
-
- $this->fuckhtml->load($d);
-
- $links =
- $this->fuckhtml
- ->getElementsByClassName(
- "cos-space-mt-xs",
- "div"
- );
-
- foreach($links as $link){
-
- $this->fuckhtml->load($link);
- $s_title =
- $this->fuckhtml
- ->getElementsByTagName(
- "h3"
- );
-
- if(count($s_title) === 0){
-
- // should not happen
- continue;
- }
-
- $data2 =
- json_decode(
- $this->fuckhtml
- ->getTextContent(
- $s_title[0]["attributes"]["data-click"]
- ),
- true
- );
-
- if(!isset($data2["clk_info"])){
-
- // wtf
- continue;
- }
-
- $data2 =
- json_decode(
- $data2["clk_info"],
- true
- );
-
- if(!isset($data2["url"])){
-
- // no link, fuck off
- continue;
- }
-
- $url =
- rawurldecode(
- $data2["url"]
- );
-
- $data =
- $this->fuckhtml
- ->getElementsByTagName(
- "p"
- );
-
- $s_description = null;
-
- if(count($data) !== 0){
-
- $data =
- json_decode(
- $this->fuckhtml
- ->getTextContent(
- $data[0]["attributes"]["sub-show-log"]
- ),
- true
- );
-
- if(isset($data["ext"]["content"])){
-
- $s_description = $data["ext"]["content"];
- }
- }
-
- $sublinks[] = [
- "title" =>
- $this->fuckhtml
- ->getTextContent(
- $s_title[0]
- ),
- "description" => $s_description,
- "url" => $url,
- "date" => null
- ];
- }
- break;
- }
- }
-
- $out["web"][] = [
- "title" => $title,
- "description" => $description,
- "url" =>
- $this->fuckhtml
- ->getTextContent(
- $datafield["attributes"]["mu"]
- ),
- "date" => $date,
- "type" => $pagetype,
- "thumb" => $image,
- "sublink" => $sublinks,
- "table" => []
- ];
-
- continue;
- }
-
- // parse special result
- $result =
- $this->fuckhtml
- ->getElementsByClassName(
- "result-op",
- [$datafield]
- );
-
- if(count($result) !== 0){
-
- //
- // Parse video carousel
- //
- if(
- isset($datafield["attributes"]["tpl"]) &&
- stripos($datafield["attributes"]["tpl"], "video") !== false
- ){
-
- preg_match(
- '/<!--s-data:([\S\s]*)-->/U',
- $datafield["innerHTML"],
- $matches
- );
-
- if(isset($matches[1])){
-
- $json =
- json_decode(
- $matches[1],
- true
- );
-
- if($json !== null){
-
- foreach($json["videoList"] as $video){
-
- $out["video"][] = [
- "title" => $video["title"],
- "description" =>
- $this->titledots(
- $video["desc"]
- ),
- "date" =>
- $this->parse_time(
- $video["pubTime"]
- ),
- "duration" =>
- $this->hms2int(
- $video["duration"]
- ),
- "views" =>
- $this->parse_viewcount(
- $video["playCount"]
- ),
- "thumb" => [
- "ratio" => "16:9",
- "url" => $video["poster"]
- ],
- "url" => $video["bindProps"]["link"]
- ];
- }
- }
- }
- continue;
- }
-
- //
- // Special result div (wiki entries, rich divs)
- //
- $title =
- $this->fuckhtml
- ->getElementsByTagName(
- "h3"
- );
-
- if(count($title) === 0){
-
- // should have a title somewhere
- continue;
- }
-
- $title =
- explode(
- ">",
- $this->fuckhtml
- ->getTextContent(
- $title[0]
- ),
- 2
- );
-
- if(count($title) === 2){
-
- $title = $title[1];
- }else{
-
- $title = $title[0];
- }
-
- // probe for wiki-like entry
- $description =
- $this->fuckhtml
- ->getElementsByClassName(
- "sc-paragraph",
- "p"
- );
-
- if(count($description) === 0){
-
- // try and get grey description
- $description =
- $this->fuckhtml
- ->getElementsByClassName(
- "c-color-gray2",
- "p"
- );
-
- if(count($description) === 0){
-
- // probe for special social media description
- $description =
- $this->fuckhtml
- ->getElementsByClassName(
- "c-color-text",
- "div"
- );
-
- if(isset($description[0]["attributes"]["aria-label"])){
-
- $description =
- $this->fuckhtml
- ->getTextContent(
- $description[0]
- ["attributes"]
- ["aria-label"]
- );
- }else{
-
- // check for news tab description
- $span =
- $this->fuckhtml
- ->getElementsByClassName(
- "c-font-normal",
- "span"
- );
-
- $description = null;
-
- foreach($span as $s){
-
- if(isset($s["attributes"]["aria-label"])){
-
- $description =
- $this->titledots(
- $this->fuckhtml
- ->getTextContent(
- $span[count($span) - 1]
- )
- );
-
- break;
- }
- }
- }
- }else{
-
- $description =
- $this->fuckhtml
- ->getTextContent(
- $description[0]
- );
- }
-
- }else{
-
- preg_match(
- '/<!--s-text-->([\S\s]*)<!--\/s-text-->/U',
- $description[count($description) - 1]["innerHTML"],
- $matches
- );
-
- if(isset($matches[1])){
-
- $description =
- $this->titledots(
- $this->fuckhtml
- ->getTextContent(
- $matches[1]
- )
- );
- }else{
-
- $description = null;
- }
- }
-
- // get thumbnail
- $thumb =
- $this->fuckhtml
- ->getElementsByTagName(
- "img"
- );
-
- if(count($thumb) !== 0){
-
- $thumb = [
- "ratio" => "1:1",
- "url" =>
- $this->unfuckthumb(
- $this->fuckhtml
- ->getTextContent(
- $thumb[0]["attributes"]["src"]
- )
- )
- ];
- }else{
-
- $thumb = [
- "ratio" => null,
- "url" => null
- ];
- }
-
- // get sublinks
- preg_match(
- '/<!--s-data:([\S\s]*)-->/U',
- $datafield["innerHTML"],
- $matches
- );
-
- $sublinks = [];
-
- if(isset($matches[1])){
-
- $json =
- json_decode(
- $matches[1],
- true
- );
-
- if($json !== null){
-
- if(isset($json["buttons"])){
-
- foreach($json["buttons"] as $button){
-
- $sublinks[] = [
- "title" => $button["text"],
- "description" => null,
- "date" => null,
- "url" => $button["url"]
- ];
- }
- }elseif(isset($json["mthreadList"])){
-
- foreach($json["mthreadList"] as $thread){
-
- $sublinks[] = [
- "title" =>
- $this->fuckhtml
- ->getTextContent(
- $thread["title"]
- ),
- "description" => null,
- "date" => null,
- "url" => $thread["ttsInfo"]["titleUrl"]
- ];
- }
- }
- }
- }
-
- // get URL
- // handle http://fakeurl.baidu.com bullshit
- $url =
- $this->fuckhtml
- ->getTextContent(
- $datafield["attributes"]["mu"]
- );
-
- if(
- preg_match(
- '/^https?:\/\/(?:fakeurl|nourl)(?:\.ubs)?\.baidu\.com/',
- $url
- )
- ){
-
- // we got some bullshit, get jumpUrl instead
- $as =
- $this->fuckhtml
- ->getElementsByTagName(
- "a"
- );
-
- if(count($as) !== 0){
-
- $url =
- $this->fuckhtml
- ->getTextContent(
- $as[0]["attributes"]["href"]
- );
- }
- }
-
- // get xueshu sublinks
- // get list
- $xueshu_list =
- $this->fuckhtml
- ->getElementsByClassName(
- "op-xueshu-links-d20-list",
- $div
- );
-
- if(count($xueshu_list) !== 0){
-
- $this->fuckhtml->load($xueshu_list[0]);
-
- $rows =
- $this->fuckhtml
- ->getElementsByClassName(
- "c-row",
- "div"
- );
-
- // remove "read more" bullshit
- foreach($rows as $row){
-
- if(strpos($row["attributes"]["class"], "op-xueshu-links-more") !== false){
-
- $xueshu_list[0]["innerHTML"] =
- str_replace(
- $row["outerHTML"],
- "",
- $xueshu_list[0]["innerHTML"]
- );
- }
- }
-
- $this->fuckhtml->load($xueshu_list[0]);
-
- foreach($rows as $row){
-
- $this->fuckhtml->load($row);
-
- if(strpos($row["attributes"]["class"], "op-xueshu-links-more") !== false){
-
- continue;
- }
-
- $as =
- $this->fuckhtml
- ->getElementsByTagName(
- "a"
- );
-
- foreach($as as $a){
-
- $sublinks[] = [
- "title" =>
- $this->titledots(
- $this->fuckhtml
- ->getTextContent(
- $a
- )
- ),
- "description" => null,
- "date" => null,
- "url" =>
- $this->fuckhtml
- ->getTextContent(
- $a["attributes"]["href"]
- )
- ];
- }
- }
- }
-
- $out["web"][] = [
- "title" => $title,
- "description" => $description,
- "url" => $url,
- "date" => null,
- "type" => "web",
- "thumb" => $thumb,
- "sublink" => $sublinks,
- "table" => []
- ];
- continue;
- }
- }
-
- //
- // Remove tracking URLs and fetch additonal image resources
- //
- $this->resolve_urls($proxy, $out, ["web", "video"]);
- $this->resolve_images($proxy, $out);
-
- return $out;
- }
-
- public function image($get){
-
- // https://image.baidu.com/search/acjson?word=asmr&rn=60&pn=0&newReq=1
- //$json = file_get_contents("scraper/baidu_img.json");
-
- if($get["npt"]){
-
- [$params, $proxy] = $this->backend->get($get["npt"], "images");
- $params = json_decode($params, true);
-
- $params["pn"] = $params["pn"] + 60;
-
- }else{
-
- $proxy = $this->backend->get_ip();
- $params = [
- "word" => $get["s"],
- "rn" => 60, // results/page
- "pn" => 0, // item increment (0 * 60)
- "newReq" => 1 // otherwise json is fucked up
- ];
-
- switch($get["sort"]){
-
- case "latest": $params["latest"] = 1; break;
- case "hot": $params["hot"] = 1; break;
- }
-
- if($get["size"] != "any"){
-
- $params["z"] = $get["size"];
- }
-
- if($get["ratio"] != "any"){
-
- $params["imgratio"] = $get["ratio"];
- }
-
- if($get["format"] != "any"){
-
- $params["imgformat"] = $get["format"];
- }
-
- if($get["color"] != "any"){
-
- $params["ic"] = $get["color"];
- }
-
- switch($get["type"]){
-
- case "hd": $params["hd"] = 1; break;
- case "isImgSet": $params["isImgSet"] = 1; break;
- case "copyright": $params["copyright"] = 1; break;
- }
- }
-
- try{
-
- $json =
- $this->get(
- $proxy,
- "https://image.baidu.com/search/acjson",
- $params,
- "https://image.baidu.com/search/index?tn=baiduimage&word=" . urlencode($get["s"])
- );
- }catch(Exception $error){
-
- throw new Exception("Failed to fetch JSON");
- }
-
- $json = json_decode($json, true);
-
- if($json === null){
-
- // detect captcha first
- $this->fuckhtml->load($json);
- $this->detect_ass();
-
- // fallback to json decode error
- throw new Exception("Failed to decode JSON");
- }
-
- if(
- isset($json["message"]) &&
- $json["message"] != "success"
- ){
-
- throw new Exception("Baidu returned an error: {$json["message"]}");
- }
-
- if(!isset($json["data"]["images"])){
-
- throw new Exception("Baidu did not return an image object");
- }
-
- $out = [
- "status" => "ok",
- "npt" => null,
- "image" => []
- ];
-
- foreach($json["data"]["images"] as $image){
-
- parse_str(parse_url($image["thumburl"], PHP_URL_QUERY), $thumb_size);
-
- $out["image"][] = [
- "title" =>
- $this->fuckhtml
- ->getTextContent(
- $image["titleShow"]
- ),
- "source" => [
- [
- "url" => $image["objurl"],
- "width" => (int)$image["width"],
- "height" => (int)$image["height"]
- ],
- [ // thumbnail
- "url" => $image["thumburl"],
- "width" => (int)$thumb_size["w"],
- "height" => (int)$thumb_size["h"]
- ]
- ],
- "url" => $image["fromUrl"]
- ];
- }
-
- //
- // Detect if there's a next page
- //
- if((int)$json["data"]["totalNum"] >= $params["pn"] + 60){
-
- $out["npt"] =
- $this->backend->store(
- json_encode($params),
- "images",
- $proxy
- );
- }
-
- return $out;
- }
-
- public function video($get){
-
- // https://www.baidu.com/sf/vsearch?pd=video&tn=vsearch&wd=jak%2Band%2Bdaxter&async=1&pn=0
- // increase &pn +20 for pagination
-
- //$html = file_get_contents("scraper/baidu_vid.html");
-
- if($get["npt"]){
-
- [$params, $proxy] = $this->backend->get($get["npt"], "videos");
- $params = json_decode($params, true);
-
- $params["pn"] = $params["pn"] + 10;
- }else{
-
- $proxy = $this->backend->get_ip();
- $params = [
- "pd" => "video",
- "tn" => "vsearch",
- "wd" => $get["s"],
- "async" => 1,
- "pn" => 0
- ];
- }
-
- try{
- $html =
- $this->get(
- $proxy,
- "https://www.baidu.com/sf/vsearch",
- $params
- );
- }catch(Exception $error){
-
- throw new Exception("Failed to get search page");
- }
-
- $html =
- str_replace(
- ["\r", "\n"],
- "",
- $html
- );
-
- $out = [
- "status" => "ok",
- "npt" => null,
- "video" => [],
- "author" => [],
- "livestream" => [],
- "playlist" => [],
- "reel" => []
- ];
-
- $html = explode("<script>", $html);
-
- foreach($html as $result){
-
- $result = trim($result);
-
- $this->fuckhtml->load($result);
-
- // get URL
- preg_match(
- '/<!-- *([^ ]*) *-->/',
- $result,
- $matches
- );
-
- if(!isset($matches[1])){
-
- // no link, give up
- continue;
- }
-
- $link = $matches[1];
-
- // get title
- $title =
- $this->fuckhtml
- ->getElementsByClassName(
- "video-title",
- "a"
- );
-
- if(count($title) === 0){
-
- // should not happen
- continue;
- }
-
- $title =
- $this->fuckhtml
- ->getTextContent(
- $title[0]
- );
-
- // get thumbnail
- $img =
- $this->fuckhtml
- ->getElementsByClassName(
- "border-radius",
- "img"
- );
-
- if(count($img) !== 0){
-
- $thumb = [
- "url" =>
- $this->unfuckthumb(
- $this->fuckhtml
- ->getTextContent(
- $img[0]["attributes"]["src"]
- )
- ),
- "ratio" => "16:9"
- ];
- }else{
-
- $thumb = [
- "url" => null,
- "ratio" => null
- ];
- }
-
- $span =
- $this->fuckhtml
- ->getElementsByTagName(
- "span"
- );
-
- // get duration
- $duration =
- $this->fuckhtml
- ->getElementsByClassName(
- "video_play_timer",
- $span
- );
-
- if(count($duration) !== 0){
-
- $duration =
- $this->hms2int(
- $this->fuckhtml
- ->getTextContent(
- $duration[0]
- )
- );
- }else{
-
- $duration = null;
- }
-
- // get author
- // 来源:哔哩哔哩
- $author =
- $this->fuckhtml
- ->getElementsByClassName(
- "wetSource",
- $span
- );
-
- if(count($author) !== 0){
-
- $author =
- explode(
- ":",
- $this->fuckhtml
- ->getTextContent(
- $author[0]
- ),
- 2
- )[1];
- }else{
-
- $author = null;
- }
-
- // get date posted
- //发布时间:2024-05-06
-
- // AND get description
- // 简介:Our first look
- $infospans =
- array_merge(
- $this->fuckhtml
- ->getElementsByClassName(
- "c-font-normal",
- $span
- ),
- $this->fuckhtml
- ->getElementsByClassName(
- "c-font-normal",
- "div"
- )
- );
-
- $date = null;
- $description = null;
-
- foreach($infospans as $infospan){
-
- $infospan =
- explode(
- ":",
- $this->fuckhtml
- ->getTextContent(
- $infospan
- ),
- 2
- );
-
- if(count($infospan) !== 2){
-
- // should not happen
- continue;
- }
-
- $infospan[1] =
- $this->fuckhtml
- ->getTextContent(
- $infospan[1]
- );
-
- switch($infospan[0]){
-
- case "发布时间": // date posted
- $date = $this->parse_time($infospan[1]);
- break;
-
- case "简介": // description
- $description = $infospan[1];
- break;
- }
- }
-
- $out["video"][] = [
- "title" => $this->titledots($title),
- "description" => $this->titledots($description),
- "author" => [
- "name" => $author,
- "url" => null,
- "avatar" => null
- ],
- "date" => $date,
- "duration" => $duration,
- "views" => null,
- "thumb" => $thumb,
- "url" => $link
- ];
- }
-
- if(count($out["video"]) === 10){
-
- // assume there's another page after this
- $out["npt"] =
- $this->backend->store(
- json_encode($params),
- "videos",
- $proxy
- );
- }
-
- return $out;
- }
-
- public function news($get){
-
- //$proxy = $this->backend->get_ip();
- //$html = file_get_contents("scraper/baidu.html");
- //$npt_data = [];
-
- if($get["npt"]){
-
- [$json, $proxy] = $this->backend->get($get["npt"], "news");
-
- $json = json_decode($json, true);
- $this->cookie = $json["cookie"];
- $npt_data = $json["req"];
-
- $npt_data["pn"] = $npt_data["pn"] + 20;
-
- try{
-
- $html = $this->get(
- $proxy,
- "https://www.baidu.com/s",
- $npt_data
- );
- }catch(Exception $error){
-
- throw new Exception("Failed to fetch search page");
- }
-
- }else{
-
- //
- // Get authentication token
- //
- $proxy = $this->backend->get_ip();
-
- $npt_data = [
- "wd" => $get["s"],
- "rn" => 20,
- "tn" => "news"
- ];
-
- // @TODO add filters
-
- try{
-
- $html = $this->get(
- $proxy,
- "https://www.baidu.com/s",
- $npt_data
- );
- }catch(Exception $error){
-
- throw new Exception("Failed to fetch search page");
- }
-
- $npt_data["pn"] = 0;
- }
-
- $data = $this->parse_search($proxy, "news", $npt_data, $html);
-
- $out = [
- "status" => "ok",
- "npt" => $data["npt"],
- "news" => []
- ];
-
- foreach($data["web"] as $article){
-
- $out["news"][] = [
- "title" => $article["title"],
- "author" => null,
- "description" => $article["description"],
- "date" => $article["date"],
- "thumb" => [
- "url" => $article["thumb"]["url"],
- "ratio" => $article["thumb"]["url"] !== null ? "16:9" : null,
- ],
- "url" => $article["url"]
- ];
- }
-
- return $out;
- }
-
- private function unfuckthumb($url){
-
- // probe for proxy URL
- $parsed_url = parse_url($url);
- if(
- preg_match(
- '/^https?:\/\/gimg(?:[0-9]+)?\.baidu\.com/',
- $url
- )
- ){
-
- $parts = explode("src=", $url);
- if(count($parts) !== 2){
-
- // shits fucked
- return $url;
- }
-
- return urldecode(explode("&", $parts[1])[0]);
- }
-
- $q = explode("&", $url, 2);
-
- if(count($q) !== 2){
-
- // shits fucked, again
- return $url;
- }
-
- // baidu devs are fucking retarded and dont follow spec:
- // &fmt=auto?s=BB32F3A050471AEC72886934030090C4&sec=1753203600&t=0fb2194775d3bd3d1bb114b818479e0a
- parse_str(str_replace("?", "&", $q[1]), $query);
-
- if(isset($query["size"])){ unset($query["size"]); }
- if(isset($query["q"])){ $query["q"] = "90"; }
-
- $query = http_build_query($query);
-
- return
- str_replace(
- $q[1],
- $query,
- $url
- );
- }
-
- private function titledots($title){
-
- return trim($title, " .\t\n\r\0\x0B…");
- }
-
- private function hms2int($time){
-
- $parts = explode(":", $time, 3);
- $time = 0;
-
- if(count($parts) === 3){
-
- // hours
- $time = $time + ((int)$parts[0] * 3600);
- array_shift($parts);
- }
-
- if(count($parts) === 2){
-
- // minutes
- $time = $time + ((int)$parts[0] * 60);
- array_shift($parts);
- }
-
- // seconds
- $time = $time + (int)$parts[0];
-
- return $time;
- }
-
- private function parse_viewcount($views){
-
- if(
- // 10k (wtf lol)
- preg_match(
- '/([0-9]+)万次/',
- $views,
- $matches
- )
- ){
-
- return (int)$matches[1] * 10000;
- }
-
- if(
- // units
- preg_match(
- '/([0-9]+)次/',
- $views,
- $matches
- )
- ){
-
- return (int)$matches[1];
- }
-
- return null;
- }
-
- private function parse_time($time){
-
- // 2023年8月7日 => yyyy/m/d
- if(
- preg_match(
- '/([0-9]{4})年([0-9]{1,2})月([0-9]{1,2})日/',
- $time,
- $matches
- )
- ){
-
- return strtotime("{$matches[1]}/{$matches[2]}/{$matches[3]}");
- }
-
- // 昨天11:45 => yesterday at 11:45
- // 昨天 => yesterday
- if(
- preg_match(
- '/昨天(.*)/',
- $time,
- $matches
- )
- ){
-
- return strtotime("Yesterday {$matches[1]}");
- }
-
- // 3天前 => 3 days ago
- if(
- preg_match(
- '/([0-9]{1,4})天前/',
- $time,
- $matches
- )
- ){
-
- return strtotime("{$matches[1]} days ago");
- }
-
- // 1个月前 => 1 month ago
- if(
- preg_match(
- '/([0-9]{1,4})个月前/',
- $time,
- $matches
- )
- ){
-
- return strtotime("{$matches[1]} months ago");
- }
-
- // attempt to parse as-is
- $time = strtotime($time);
-
- if($time !== false){
-
- return $time;
- }
-
- return null;
- }
-
- private function detect_ass(){
-
- $as =
- $this->fuckhtml
- ->getElementsByTagName(
- "a"
- );
-
- if(
- count($as) === 0 ||
- preg_match(
- '/^https?:\/\/wappass\.baidu\.com\/static\/captcha/',
- $this->fuckhtml
- ->getTextContent(
- $as[0]["attributes"]["href"]
- )
- )
- ){
-
- throw new Exception("Baidu returned a Captcha");
- }
- }
- }
|