今天心血来潮,想采集一个站点,做个自己的内容站,
想着还是不错的,可是在查看的过程中,发现此站是防盗链的,
一般请求是 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);
}
}