今天心血来潮,想采集一个站点,做个自己的内容站,
想着还是不错的,可是在查看的过程中,发现此站是防盗链的,
一般请求是 403 没有访问权限,这怎么办?
像简单的
file_get_contents()
fopen()
这样的函数肯定是不能用的了。
想到了一个curl 命令 可以模拟浏览器的请求,去访问,这样就可以了吧。
说来就来,怀揣着怀疑的态度做个测试吧:
我这个框架是使用了yaf进行了封装,下面是我一个controller中的一个调用:
意思是采集 这张图片,存放在本地
NewsModel.php 给出代码
fetchBefore 这个方法是 curl发出请求之前触发,添加header头信息,
这些header头从Charles 抓包工具中截取出来的,放在了这里
geturl 方法 使用file_put_contents() 把请求的内容存放在了本地
class NewsModel extends BaseModel { protected function _init() { parent::_init(); $this->_host = 'http://g.yt99.com'; //$this->_host = 'http://k.yt99.com'; } public function fetchBefore($url, $data) { //$this->setRequestOptions(CURLOPT_COOKIE,'acw_tc=dede581e15416489660366317ece9fedad784adaaeedf1582f420846de'); $this->setRequestHeader([ "accept" => "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", "accept-encoding" => "gzip, deflate, br", "accept-language" => "zh-CN,zh;q=0.9", "cache-control" => "no-cache", "pragma" => "no-cache", "upgrade-insecure-requests" => "1", "user-agent" => "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36" ]); return $data; } protected function fetchFinish($data) { return $data; } public function geturl($imageurl, $param = []) { $result = $this->send($imageurl, $param); echo file_put_contents(APP_PATH . DS . 'c.gif', $result); } }
程序运行后:
打开本地文件,可以看到:
已经成功的把文件down下来了。
最后结论:
1、防盗链不要愉,可能 通过采取反防盗链的方式去获取
2、抓包工具截取 request header 头信息 通过判断、测试 猜测服务器需要哪些header头信息进行传递
多次试探后,应该就能成功。当然,如果特别复杂的盗链是不能破解的。呵呵
好,这次把一次反盗链的方式方法记录下来,以后可能用到。
curl.php
class Curl{ private $_curl; private $response_header_continue = FALSE; private $_cookies; private $_reqHeaders; public function __construct(array $defaultOptions = []) { $this->_curl = curl_init(); $this->setOption(CURLOPT_HEADERFUNCTION, [$this, 'addResponseHeaderLine']); } public function addResponseHeaderLine($curl, $header_line) { $trimmed_header = trim($header_line, "\r\n"); if ($trimmed_header === "") { $this->response_header_continue = FALSE; } else if (strtolower($trimmed_header) === 'http/1.1 100 continue') { $this->response_header_continue = TRUE; } else if (!$this->response_header_continue) { $this->response_headers[] = $trimmed_header; } return strlen($header_line); } public function setHeader(array $data) { $this->_reqHeaders = array_replace($this->_reqHeaders, $data); foreach ($this->_reqHeaders as $key => $value) { if ($value !== NULL) { $header[] = is_integer($key) ? $value : $key . ': ' . $value; } } $this->_options[CURLOPT_HTTPHEADER] = $header; //CURLOPT_COOKIE } public function getOption($key) { return isset($this->_options[$key]) ? $this->_options[$key] : NULL; } public function setOption($key, $value) { $this->_options[$key] = $value; } public function setCookie($key, $val) { $this->_cookies[$key] = $val; $this->setOption(CURLOPT_COOKIE, http_build_query($this->_cookies, '', '; ')); } public function getResponseHeaders($headerKey = NULL) { $headers = []; $headerKey = strtolower($headerKey); foreach ($this->response_headers as $header) { $parts = explode(":", $header, 2); $key = isset($parts[0]) ? $parts[0] : NULL; $value = isset($parts[1]) ? $parts[1] : NULL; $headers[trim(strtolower($key))] = trim($value); } if ($headerKey) { return isset($headers[$headerKey]) ? $headers[$headerKey] : FALSE; } return $headers; } public function __destruct() { curl_close($this->_curl); } }