欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

访客身份抓取新浪微博视频。Sina Visitor System

程序员文章站 2022-03-25 13:29:24
...

最近要抓取写新浪微博的视频。怎知新浪微博(几乎)整站都启用了Sina Visitor System系统。即使无需登录就能访问的页面,也需要获得一个访客cookie才能访问。翻了下百度几乎都是模拟登录来抓取数据的。可我不需要那么复杂,于是就自己干了。

先清除了浏览器cookie 模拟下访问我要抓取的视频 http://weibo.com/tv/v/Fs7ztjjfL?from=vhot。Fiddler截图如下。访客身份抓取新浪微博视频。Sina Visitor System大致分了一下几部。

1.访问 genvisitor 获取一个tid.

2.用tid 先获取一个 cookie,同时得到2个参数 sub subp。3.带着获得的cookie,和sub subp 2个参数 获得第二个cookie。

4.最后用第二个cookie访问要抓取的页面。

其实 新浪的访客系统的源文件已经写的很清楚如何获得访客身份了。如图访客身份抓取新浪微博视频。Sina Visitor System

最后贴下代码:

<?php

class Vgather extends base {
 

    /**
     * 
     * 由于weibo防爬虫需要获得访客身份cookie后在访问,大致流程如下。
     * 获得tid->请求一个访客cookie->请求一个跨域cookie->抓去数据。
     * @param string $url
     * @author maskxu 
     */
    public function catch_html($url)
    {
        $this->init_redis();
        $ckey = 'gooseeker_weibo_video_cookie';
        $xcookie = $this->redis->get($ckey);
        //如果redis缓存的cookie过期,重新获取。
        if(empty($xcookie))
        {
            //获得tid
            $tid = $this->_get_tid();
            $cookie = $this->_get_cookie($tid, $sub, $subp);
            if(empty($sub)) //sub 可能会获取失败,原因未知,可能是因为频繁访问.
            {
                //throw new Exception("Get Sub error", 1);
                return false;
            }
            $xcookie =$this->_get_crosscookie($sub, $subp,$cookie);
            $this->redis->set($ckey, $xcookie ,3600*24*7);
            $rst = $this->redis->get($ckey);
        }
        $content = $this->_curl_data($url,"GET","",false,$xcookie,false);
        return $content;
    }

    //获得tid
    private function _get_tid()
    {
        $postdata['cb'] = "gen_callback";
        $postdata['fp'] = '{"os":"1","browser":"Chrome61,0,3163,100","fonts":"undefined","screenInfo":"1920*1080*24","plugins":"Portable Document Format::internal-pdf-viewer::Chrome PDF Plugin|::mhjfbmdgcfjbbpaeojofohoefgiehjai::Chrome PDF Viewer|::internal-nacl-plugin::Native Client|Enables Widevine licenses for playback of HTML audio/video content. (version: 1.4.8.1008)::widevinecdmadapter.dll::Widevine Content Decryption Module"}';
        $url = "https://passport.weibo.com/visitor/genvisitor";
        $content = $this->_curl_data($url,"POST",$postdata);
        preg_match('/"tid":"(.*)",/i', $content, $matches);
        $tid = $matches[1];
        return $tid;
    }
    //第一次获得cookie. sub,subp,cookie是第二次获得跨域cookie必须的.
    private function _get_cookie($tid,&$sub,&$subp)
    {
        $url = "https://passport.weibo.com/visitor/visitor?";
        $url .= 'a=incarnate&t='.urlencode($tid).'&w=2&c=095&gc=&cb=crossdomain&from=weobo&rand=0.'.rand();
        $cookie="";
        $content = $this->_curl_data($url,"GET","",true,$cookie);
        preg_match('/"sub":"(.*)",/i', $content, $matches);
        $sub = $matches[1];
        preg_match('/"subp":"(.*)"}/i', $content, $matches);
        $subp = $matches[1];
        return $cookie;
    }
    //第二次获得跨域xcookie
    private function _get_crosscookie($sub, $subp,$cookie)
    {
        $url = "https://passport.weibo.com/visitor/visitor?";
        $url .= 'a=crossdomain&cb=return_back&s='.$sub.'&sp='.$subp.'&w=2&from=weibo&rand=0.'.rand();
        $content = $this->_curl_data($url,"GET","",true,$cookie);
        return $cookie;
    }

    
    private function _curl_data($url,$method="GET",$postdata="",$ssl=false,&$cookie="",$show_header=true )
    {
 
        $ch = curl_init();
        curl_setopt($ch,CURLOPT_URL,$url );
        curl_setopt($ch,CURLOPT_USERAGENT,'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36');//模拟UA
        if($show_header)
            curl_setopt($ch, CURLOPT_HEADER, 1);  //show header 为了拿到cookie
        if($method == "POST")
        {
            curl_setopt($ch,CURLOPT_POST,1);//使用post提交数据  
            curl_setopt($ch,CURLOPT_POSTFIELDS,$postdata);//设置 post提交的数据
        }
        if($ssl)
        {
            // curl_setopt($ch, CURLOPT_SSLVERSION, 3); //设定SSL版本  
            // 对认证证书来源的检查,0表示阻止对证书的合法性的检查。  
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            // 从证书中检查SSL加密算法是否存在  
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, true);
        }
        if($cookie != "")
        {
            curl_setopt($ch, CURLOPT_COOKIE, $cookie); 
        }
        curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);//关闭直接输出 
        $data = curl_exec($ch);
        if($show_header)
        {
            preg_match_all('|Set-Cookie: (.*);|U', $data, $results);
            if(count($results)>1)
                $cookie = implode(';', $results[1]);
        }
        curl_close($ch);
        return $data ;
    }

 
}

?>