cURL 是一个利用 URL 语法规定来传输文件和数据的工具,支持很多协议,如 HTTP、FTP、TELNET 等。最爽的是,PHP 也支持 cURL 库。使用 PHP 的 cURL 库可以简单和有效地去抓网页。你只需要运行一个脚本,然后分析一下你所抓取的网页,然后就可以以程序的方式得到你想要的数据了。无论是你想从从一个链接上取部分数据,或是取一个XML文件并把其导入数据库,那怕就是简单的获取网页内容.
GET请求带参数的时候,一定要转换成字符串形式http_build_query($post_data)
,不可以使用数组
CURLOPT_FOLLOWLOCATION 用于重定向的请求,有重定向的页面直接curl 访问可能会访问不到,使用这个参数即可
CURLOPT_SSL_VERIFYHOST 设置为 1 是检查服务器SSL证书中是否存在一个公用名(common name)。译者注:公用名(Common Name)一般来讲就是填写你将要申请SSL证书的域名 (domain)或子域名(sub domain)。 设置成 2,会检查公用名是否存在,并且是否与提供的主机名匹配。 0 为不检查名称。 在生产环境中,这个值应该是 2(默认值)。
脚本最大的执行时间是30S 这个时间并不是说30S之内请求数据的等待时间,而是说总共请求的时间,请求30S之后,就不在请求。会类似于 die 的作用。如果想取消时间限制,可以使用 set_time_limit(0);
curl -X POST -H 'Content-Type: application/json' 'https://xxx.com' -d 'string'
protected function post($url, $params, $headers = [], $is_json = false)
{
//初始化
$curl = curl_init();
//设置抓取的url
curl_setopt($curl, CURLOPT_URL, $url);
//设置头文件的信息作为数据流输出
curl_setopt($curl, CURLOPT_HEADER, 0);
//设置获取的信息以文件流的形式返回,而不是直接输出。
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
if ($headers) {
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
}
// post 请求的处理
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_URL, $url);
// json 请求处理
if ($is_json) {
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($params));
if ($headers) {
$head_str = implode(',', $headers);
curl_setopt($curl, CURLOPT_HTTPHEADER, ['Content-Type: application/json', $head_str]);
} else {
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
}
} else {
curl_setopt($curl, CURLOPT_POSTFIELDS, $params);
}
//执行命令
$data = curl_exec($curl);
//关闭URL请求
curl_close($curl);
//显示获得的数据
return $data;
}
请求 demo
$auth = base64_encode($this->app_id . ':' . $this->app_key);
$headers = ['Authorization:' . 'Basic ' . $auth];
$response = $this->post($this->get_token_url, ['grant_type' => 'client_credentials'], $headers);
/**
* @param $url 请求网址
* @param bool $params 请求参数
* @param int $ispost 请求方式
* @param int $https https协议
* @param int $cookie 是否传递 cookie
* @param int $proxy 是否需要代理
* @return bool|mixed
*/
function curl($url, $params = false, $ispost = 0, $https = 0, $cookie = 0, $proxy = 0)
{
$httpInfo = array();
set_time_limit(0); // 默认脚本是请求30S,添加这个参数会一直请求,没有时间限制
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36');
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30); // 这个是连接的时间,也就是多久503 timeout
curl_setopt($ch, CURLOPT_TIMEOUT, 300); // 这个是执行的时间 最好不要设置太短
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 返回原生的内容
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // 如果请求的数据有重定向,则追踪到重定向地址
if ($https) {
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); // 对认证证书来源的检查
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); // 从证书中检查SSL加密算法是否存在
}
if ($ispost) {
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_URL, $url);
} else {
if ($params) {
if (is_array($params)) {
$params = http_build_query($params);
}
curl_setopt($ch, CURLOPT_URL, $url . '?' . $params);
} else {
curl_setopt($ch, CURLOPT_URL, $url);
}
}
if ($cookie) {
curl_setopt($ch, CURLOPT_COOKIE, $cookie); // 注意,这个cookie 是需要你先登陆再去浏览器获取的
}
if ($proxy) {
$proxyport = '8080'; // 注意这里的端口号需要自己设置
curl_setopt($ch, CURLOPT_PROXY, $proxy);
curl_setopt($ch, CURLOPT_PROXYPORT, $proxyport);
}
$response = curl_exec($ch);
if (curl_errno($ch)) {
echo "Error Occured in Curl\n";
echo "Error number: " . curl_errno($ch) . "\n";
echo "Error message: " . curl_error($ch) . "\n";
curl_close($ch);
return false;
} else {
// $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); // 有出现报错的时候,可以打印
// $httpInfo = array_merge($httpInfo, curl_getinfo($ch));
curl_close($ch);
return $response;
}
}
使用方法
// 发送请求
$result = self::curl('网址', '参数', true);
// 收到的数据需要转化一下
$json = json_decode($result);
- 如果我们输出内容发现有乱码,我们尝试
json_decode()
发现是不可以转换的。这个时候一般是GBK
格式,我们只需要把结果转换一下即可
$response = iconv('GBK//IGNORE', 'UTF-8', $response);
$res = json_decode($response);
var_dump($res);
请求的时候带
cookie
;如果有多个参数,中间用分号;
隔开
curl_setopt($ch,CURLOPT_COOKIE, "g=".$token.';'.'PHPSESSID='.$_COOKIE['PHPSESSID'] );
cookie
文件的使用
$cookie_file = "/tmp/tmp/cookies.txt";
function store_cookies($cookie_file)
{
//连接关闭以后,存放cookie信息的文件名称 (cookies stored in $cookie_file)
curl_setopt ($this->ch, CURLOPT_COOKIEJAR, $cookie_file);
//包含cookie信息的文件名称,这个cookie文件可以是Netscape格式或者HTTP风格的header信息
curl_setopt ($this->ch, CURLOPT_COOKIEFILE, $cookie_file);
}
注意
如果本地文件
curl
请求本地文件,需要传递session
的话,有可能会出现只能请求一次的情况,再请求会失败。解决这个问他的方式是在执行curl_exec($ch)
之前,执行session_write_close()
。这个我查询文档是关闭会话的意思。但是如果请求其他站点就不需要这个处理了
查阅资料,这么解释
这是php session锁死的一种情况
使用session过程中,在开启session后,同一浏览器,执行同一程序,不同页面会被锁。不同浏览器不会出现这种情况。
结合了PHP的Session机制,找到了阻塞的原因。
由于PHP的Session信息是写入文件的,1个客户端占有1个session文件。
因此,当 session_start被调用的时候,该文件是被锁住的,而且是以读写模式锁住的
(因为程序中可能要修改session的值),这样,第2次调用 session_start的时候就被阻塞了。
包含头信息,来源位置
$useragent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)";
function set_user_agent($useragent)
{
//在HTTP请求中包含一个”user-agent”头的字符串
curl_setopt($this->ch, CURLOPT_USERAGENT, $useragent);
}
//来源位置
$referrer_url = 'http://www.google.com'
function set_referrer($referrer_url)
{
//设置header中"Referer: " 部分的值
curl_setopt($this->ch, CURLOPT_REFERER, $referrer_url);
}
//在启用CURLOPT_RETURNTRANSFER时候将获取数据返回
curl_setopt($this->ch, CURLOPT_RETURNTRANSFER,true);
// 允许重新定向
curl_setopt($this->ch, CURLOPT_FOLLOWLOCATION, true);
// 如果有gzip则解压
curl_setopt($this->ch,CURLOPT_ENCODING , 'gzip, deflate ,sdch');
//HTTP认证
function set_credentials($username,$password)
{
curl_setopt($this->ch, CURLOPT_USERPWD, "$username:$password");
}
使用代理
url
请求
$proxyport = "808";
curl_setopt($ch,CURLOPT_PROXY,$proxy);
curl_setopt($ch,CURLOPT_PROXYPORT,$proxyport);
设置
POST
请求
curl_setopt ( $ch, CURLOPT_POST, 1 ); //设置POST请求
curl_setopt ( $ch, CURLOPT_HTTPHEADER, array (
'Content-type:application/x-www-form-urlencoded;charset=UTF-8'
) );
curl_setopt ( $ch, CURLOPT_POSTFIELDS, $data ); //请求参数
curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, true );
使用
json
格式请求
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($data))
);
HTML
高亮显示
//高亮HTML $line_number 显示行号
function highlightHtml($code,$line_number=false)
{
//$code=$this->results;
$code = htmlspecialchars($code);
//$code = str_replace(" "," ",$code); //替换空格替换为
//$code = nl2br($code); //将回车替换为<br>
//htm标签
//$code = preg_replace_callback('/<([a-zA-Z0-9]+)(.*?)(\/?>)/',array('WebLoad','__pv'), $code);
$code = preg_replace('/(<[a-zA-Z0-9]+)/', '<font color="#0000FF">$1</font>', $code);
$code = preg_replace('/(<\/[a-zA-Z0-9]+>)/', '<font color="#0000FF">$1</font>', $code);
$code = preg_replace('/(\/>)/', '<font color="#0000FF">${1}</font>', $code);
//$code = preg_replace('/(<\/?[a-zA-Z]+ .*?>)/','<font color="#0000FF">${1}</font>', $code);
$code = preg_replace('/<!DOCTYPE\s+.+?>/','<font color="#3300FF">${0}</font>',$code);
//注释
$code = str_replace('<!--', '<font color="#666666"><em><!--', $code);
$code = str_replace('-->', '--></em></font>', $code);
//--------------以下是专为visualTpl模板文件而定制的高亮代码--------
//block : begin|end
$code = preg_replace('/(<!--\s*)(begin|end)(\s+)([a-z_\x7f-\xfe]+)/i','${1}<font size="" color="#0000FF"><b>${2}</b></font>${3}<b><font color="#FF0000">${4}</font></b>', $code);
$code = preg_replace('/(\$[a-z0-9_]+)\s*=\s*(per|on)\(([0-9]+),(\'.*?\'),(\'.*?\')\)/i','<font color="#009900"><b>${1}</b></font>=<font color="#0000FF">${2}</font>(${3},<font color="#FF9999">${4}</font>,<font color="#FF9999">${5}</font>)', $code);
//vip : vip|endvip
$code = preg_replace('/<font color="#666666"><em><!--\s*vip/i', '<span style="display:block;border:1px dashed #696969;padding 3px" >${0}', $code);
$code = preg_replace('/<!--\s*endvip\s*--><\/em><\/font>/i', '${0}</span>', $code);
//ssi : #include
$code = preg_replace('/<!--\s*#include\s+file.+?-->/i','<span style="background-color:#FFFF66; font-weight:bold; font-style:normal;padding:3px">${0}</span>',$code);
//无格式变量
$code = preg_replace('/(\{\$[a-zA-Z0-9_\x7f-\xfe]+\})/','<font style="background-color:#D7FED1;padding:1px" color="#009900">${1}</font>', $code);
//格式变量
$code = preg_replace('/(\{\$[a-zA-Z0-9_\x7f-\xfe]+;)([a-zA-Z]+)=\'([^\']+?)\'\}/','<font style="background-color:#D7FED1;padding:1px" color="#009900">${1}<font color="#CC0000">${2}</font>=<font color="#FF33CC">\'${3}\'</font>}</font>', $code);
//--------------定制代码结束--------------
//$code = preg_replace_callback('/>[^<]+?</',array('WebLoad','__htmlspace'), $code);
//$code = nl2br($code);
if(! $line_number){
return '<PRE>'.$code.'</PRE>';
}else{
$code = '<pre><ol><li>' . str_replace("\n",'</li><li>',$code) . '</li></ol></pre>';
return $code;
}
}
class Spider {
public function downloadImage($url, $path='images/')
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
$file = curl_exec($ch);
curl_close($ch);
$this->saveAsImage($url, $file, $path);
}
private function saveAsImage($url, $file, $path)
{
$filename = pathinfo($url, PATHINFO_BASENAME);
$resource = fopen($path . $filename, 'a');
fwrite($resource, $file);
fclose($resource);
}
}
使用
$images = [
'https://dn-laravist.qbox.me/2015-09-22_00-17-06j.png',
'https://dn-laravist.qbox.me/2015-09-23_00-58-03j.png'
];
$spider = new Spider();
foreach ( $images as $url ) {
$spider->downloadImage($url);
}
发送
XML
数据
function senXml($url,$xmlData)
{
$header[] = "Content-type: text/xml"; //定义content-type为xml,注意是数组
$ch = curl_init ($url);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch, CURLOPT_HTTPHEADER,$header);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch,CURLOPT_POSTFIELDS, $xmlData);
$response = curl_exec($ch);
if(curl_errno($ch)){
printcurl_error($ch);
}
curl_close($ch);
}
除了curl
,还有以下获取数据的请求方式
/*发送数据 */
function send_post($url, $post_data)
{
$postdata = http_build_query($post_data);
$options = array(
'http' => array(
'method' => 'POST',
'header' => 'Content-type:application/x-www-form-urlencoded',
'content' => $postdata,
'timeout' => 15 * 60
) // 超时时间(单位:s)
);
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
return $result;
}
以下这种方式请求得到xml
格式数据
我不知道自己的
MAC
环境为什么不可行,但是有朋友的linux
和win
是可以的。
function get1($dataStr){
$xhr = new COM("MSXML2.XMLHTTP");
$xhr->open("GET",$dataStr,false);
$xhr->send();
$res=$xhr->responseText;
return $res;
}
function postCurl($data)
{
$ch = curl_init(self::conf()['api_url']);
curl_setopt($ch, CURLOPT_POST, true);
// ssl的屏蔽
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
return curl_exec($ch);
}