| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460 |
- <?php
- class baidu{
-
- public function __construct(){
-
- include "lib/backend.php";
- $this->backend = new backend("baidu");
-
- include "lib/fuckhtml.php";
- $this->fuckhtml = new fuckhtml();
-
- $this->proc = curl_multi_init();
- $this->handles = [];
- $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\.|m\.)?baidu\.com\/(?:link\?|from=0\/)/',
- $url
- ) === 0
- ){
-
- // not a baidu redirect
- return $url;
- }
-
- $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[] = [
- "replacement" => $url,
- "handle" => $curlproc
- ];
-
- return $url;
- }
-
- private function resolve_urls(&$scraped_data){
-
- do{
- do{
- $status = curl_multi_exec($this->proc, $active);
- }while($status === CURLM_CALL_MULTI_PERFORM);
- if($active){
- curl_multi_select($this->proc);
- }
- }while($active && $status === CURLM_OK);
-
- //
- // if we reach this, we're done downloading garbage
- //
-
- // parse redirect values & create data shit
- $keys = [];
- $replacements = [];
-
- for($i=0; $i<count($this->handles); $i++){
-
- preg_match(
- '/window\.location\.replace\("([^"]+)"\)/',
- curl_multi_getcontent($this->handles[$i]["handle"]),
- $location
- );
-
- if(
- preg_match(
- '/^(https?:|)\/\//',
- $location[1]
- )
- ){
-
- $keys[] = $this->handles[$i]["replacement"];
- $replacements[] = $location[1];
- }
- }
-
- $this->recursive_replace($keys, $replacements, $scraped_data);
-
- curl_multi_close($this->proc);
- }
-
- private function recursive_replace(&$keys, &$replacements, &$pointer){
-
- foreach($pointer as $key => &$value){
-
- if($key == "url"){
-
- $search =
- array_search(
- $value,
- $keys
- );
-
- if($search !== false){
-
- // replace url
- $value = $replacements[$search];
- }
-
- }elseif(is_array($value)){
-
- $this->recursive_replace($keys, $replacements, $value);
- }
- }
- }
-
- public function web($get){
-
- if($get["npt"]){
-
- [$json, $proxy] = $this->backend->get($get["npt"], "web");
-
- $json = json_decode($json, true);
- $this->cookie = $json["cookie"];
- $target = $json["target"];
-
- try{
-
- $html = $this->get(
- $proxy,
- $target,
- []
- );
- }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 = [
- "word" => $get["s"]
- ];
-
- // &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://m.baidu.com/s",
- $npt_data
- );
- }catch(Exception $error){
-
- throw new Exception("Failed to fetch search page");
- }
- //$html = file_get_contents("scraper/baidu.html");
- }
-
- return $this->parse_search($proxy, "web", $html);
- }
-
- private function parse_search($proxy, $pagetype, $html){
-
- // hack, maybe not needed anymore
- $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();
-
- // get next page
- $npt =
- $this->fuckhtml
- ->getElementsByClassName(
- "new-nextpage-only",
- "a"
- );
-
- if(count($npt) === 0){
-
- $npt =
- $this->fuckhtml
- ->getElementsByClassName(
- "new-nextpage",
- "a"
- );
- }
-
- if(count($npt) !== 0){
-
- $out["npt"] =
- $this->backend->store(
- json_encode([
- "cookie" => $this->cookie,
- "target" =>
- $this->fuckhtml
- ->getTextContent(
- $npt[0]["attributes"]["href"]
- )
- ]),
- "web",
- $proxy
- );
- }
-
- // get "articles"
- $articles =
- $this->fuckhtml
- ->getElementsByTagName(
- "article"
- );
-
- foreach($articles as $article){
-
- //print_r($article);
-
- $this->fuckhtml->load($article);
-
- if(
- !isset($article["attributes"]["rl-link-data-ivk"]) &&
- !isset($article["attributes"]["data-click-info"])
- ){
-
- // probe for related searches
- $relateds =
- $this->fuckhtml
- ->getElementsByClassName(
- "sc-sublink",
- "button"
- );
-
- foreach($relateds as $related){
-
- $out["related"][] =
- $this->fuckhtml
- ->getTextContent(
- $related
- );
- }
- continue;
- }
-
- // find json object
- $jsons = [];
-
- if(isset($article["attributes"]["rl-link-data-ivk"])){ $jsons[] = &$article["attributes"]["rl-link-data-ivk"]; }
- if(isset($article["attributes"]["data-click-info"])){ $jsons[] = &$article["attributes"]["data-click-info"]; }
- if(isset($article["attributes"]["rl-link-data-log"])){ $jsons[] = &$article["attributes"]["rl-link-data-log"]; }
-
- // fail
- if(count($jsons) === 0){ continue; }
-
- $url = null;
-
- foreach($jsons as $json){
- $json =
- json_decode(
- $this->fuckhtml
- ->getTextContent(
- $json
- ),
- true
- );
-
- $url = null;
- if(isset($json["control"]["dataUrl"])){
-
- $url = $json["control"]["dataUrl"];
- break;
- }elseif(isset($json["control"]["default_url"])){
-
- $url = $json["control"]["default_url"];
- break;
- }elseif(isset($json["extra"])){
-
- // decode extra object
- $json2 = json_decode($json["extra"], true);
-
- if(isset($json2["url"])){
-
- // double chinese encryption
- $url = rawurldecode(rawurldecode($json2["url"]));
- break;
- }
-
- if(isset($json2["loc"])){
-
- $url = rawurldecode(rawurldecode($json2["loc"]));
- break;
- }
- }
- }
-
- // fail
- if($url === null){
-
- if(isset($article["attributes"]["rl-link-href"])){
-
- $url =
- $this->fuckhtml
- ->getTextContent(
- $article["attributes"]["rl-link-href"]
- );
- }else{
-
- // horrible fail
- continue;
- }
- }
-
- // get title
- $title =
- $this->fuckhtml
- ->getElementsByAttributeValue(
- "role",
- "title",
- "div"
- );
-
- if(count($title) === 0){
-
- $title =
- $this->fuckhtml
- ->getElementsByClassName(
- "cosc-title-slot",
- "span"
- );
- }
-
- if(count($title) === 0){
-
- $title =
- $this->fuckhtml
- ->getElementsByClassName(
- "cu-title",
- "p"
- );
- }
-
- if(count($title) !== 0){
-
- $title =
- $this->titledots(
- $this->fuckhtml
- ->getTextContent(
- $title[0]
- )
- );
- }else{
-
- $title = "Untitled";
- }
-
- // get description
- $description =
- $this->fuckhtml
- ->getElementsByAttributeValue(
- "data-module",
- "abstract",
- "div"
- );
-
- if(count($description) === 0){
-
- $description =
- $this->fuckhtml
- ->getElementsByAttributeValue(
- "role",
- "text",
- "div"
- );
- }
-
- if(count($description) === 0){
-
- $description =
- $this->fuckhtml
- ->getElementsByClassName(
- "cos-gutter",
- "div"
- );
- }
-
- if(count($description) !== 0){
-
- $description =
- $this->titledots(
- $this->fuckhtml
- ->getTextContent(
- $description[0]
- )
- );
- }else{
-
- $description = null;
- }
-
- // get date
- $date =
- $this->fuckhtml
- ->getElementsByClassName(
- "cosc-source-caption",
- "span"
- );
-
- if(count($date) !== 0){
-
- $date =
- $this->parse_time(
- $this->fuckhtml
- ->getTextContent(
- $date[0]
- )
- );
- }else{
-
- $date = null;
- }
-
- // get thumb
- $image =
- $this->fuckhtml
- ->getElementsByClassName(
- "cos-image-body",
- "img"
- );
-
- if(count($image) !== 0){
-
- $thumb = [
- "ratio" => "16:9",
- "url" =>
- $this->fuckhtml
- ->getTextContent(
- $image[0]["attributes"]["src"]
- )
- ];
- }else{
-
- $thumb = [
- "ratio" => null,
- "url" => null
- ];
- }
-
- $out["web"][] = [
- "title" => $title,
- "description" => $description,
- "url" => $this->redirect_add_url($proxy, $url),
- "date" => $date,
- "type" => "web",
- "thumb" => $thumb,
- "sublink" => [],
- "table" => []
- ];
- }
-
- // dedup related searches
- $out["related"] = array_values(array_unique($out["related"]));
-
- $this->resolve_urls($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");
- }
- }
- }
|