跨域、curl、snoopy、file_get_contents()
定义:可以称为”信息采集/模拟登录”技术,可以实现对某个地址做请求,同时按照要求传递get或post参数。
curl本身是php的一个扩展,同时也是一个利用URL语法规定来传输文件和数据的工具,支持很多协议,如HTTP、FTP、TELNET等。
php中还有file_get_contents()方式,也可。
原理,要获取其他网站的数据首先要获取网页内容,然后在网页内容中提取我们需要的数据。要获取网站数据可以通过程序获取网站源码,然后通过正则表达式匹配出所需数据保存到数据库中。
什么是跨域?
跨域访问就是你在一个域环境下,访问另一个域的内容。
因为javascript同源策略的限制,a.com 域名下的js脚本无法操作b.com或是c.a.com域名下的对象。
Ajax的应用中,由于安全的问题,浏览器默认是不支持 javascript跨域调用的。
1.主域相同,子域不同,如xxx.aaa.com和yyy.aaa.com
2.域名相同,端口不同,如xxx.aaa.com:8000和 xxx.aaa.com
3.域名相同,协议不同,如http://www.aaa.com/和 https://www.aaa.com/
4.主机相同,用ip和域名的,http://127.0.0.1/和 http://localhost/
eg.
信息采集时通过程序将非结构化的信息从大量的网页中抽取出来保存到结构化的数据库中,在最短的时间内把最新的信息从不同的Internet站点上抓取下来,提高信息及时性和节省或减少工作量。
实现采集常用函数
curl系列函数
Snoopy封装类
file_get_contents()
curl实现:
注意,PHP中需要开启扩展
// 初始化,创建一个新 cURL 资源
$ch = curl_init(); // 设置 URL 和相应的选项
$options = array(CURLOPT_URL => 'http://www.baidu.com/',
CURLOPT_HEADER => false
); curl_setopt_array($ch, $options);//也可以使用curl_setopt,但是这样就需要重复定义了 // 执行,抓取 URL 并把它传递给浏览器获取html内容
curl_exec($ch); // 关闭 cURL 资源,并且释放系统资源
curl_close($ch);
curl的错误处理:
$output = curl_exec($ch);
if ($output === FALSE) {
echo "cURL Error: " . curl_error($ch);
}
注意,比较的时候我们用的是“=== FALSE”,而非“== FALSE”。因为我们得区分 空输出 和 布尔值FALSE,后者才是真正的错误
获取信息:
这是另一个可选的设置项,能够在cURL执行后获取这一请求的有关信息:
curl_exec($ch);
$info = curl_getinfo($ch);
echo '获取'. $info['url'] . '耗时'. $info['total_time'] . '秒';
// ...
返回的数组中包括了以下信息:
# “url” //资源网络地址
# “content_type” //内容编码
# “http_code” //HTTP状态码
# “header_size” //header的大小
# “request_size” //请求的大小
# “filetime” //文件创建时间
# “ssl_verify_result” //SSL验证结果
# “redirect_count” //跳转技术
# “total_time” //总耗时
# “namelookup_time” //DNS查询耗时
# “connect_time” //等待连接耗时
# “pretransfer_time” //传输前准备耗时
# “size_upload” //上传数据的大小
# “size_download” //下载数据的大小
# “speed_download” //下载速度
# “speed_upload” //上传速度
# “download_content_length”//下载内容的长度
# “upload_content_length” //上传内容的长度
# “starttransfer_time” //开始传输的时间
# “redirect_time”//重定向耗时
模拟post方式传递数据:
$url = "local-credit.cn/site/login";
$post_data = array (
"username" => "admin",
"password" => 'pwd',
"rememberMe" => 0
);
$ch = curl_init();
$options = array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_POST => 1,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_POSTFIELDS => $post_data
);
curl_setopt_array($ch,$options);
//curl_setopt($ch, CURLOPT_URL, $url); //设置请求地址
//curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//返回请求的信息
// 我们在POST数据哦!
//curl_setopt($ch, CURLOPT_POST, 1);
//忽略ssl认证文件
//curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
//curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
// 把post的变量加上
//curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
$output = curl_exec($ch);
if ($output === FALSE) {
echo "cURL Error: " . curl_error($ch);
}
curl_close($ch);
print_r($output);
记一下,真实日常接口调试的post模拟请求:
$url = "local-appapi.cn/user/login";
$header = array('token:123456','os:android','version-code:1');
$post_data = array (
"mobile" => "",
"password" => 'c64759a4137fc56cd55babad6f940fb9'
);
$ch = curl_init();
$options = array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => ,////返回请求的信息
CURLOPT_POST => ,//规定post请求
CURLOPT_SSL_VERIFYPEER => false,//忽略ssl认证文件
CURLOPT_SSL_VERIFYHOST => false,//忽略ssl认证文件
CURLOPT_POSTFIELDS => $post_data,//post的变量数据
CURLOPT_TIMEOUT => ,//响应时间
CURLOPT_HTTPHEADER => $header//header头信息
);
curl_setopt_array($ch,$options);
$output = curl_exec($ch);
if ($output === FALSE) {
echo "cURL Error: " . curl_error($ch);
}
curl_close($ch);
print_r($output);
因为是在本地跨项目进行curl调动,且php-cgi端口默认统一是9000,端口被占用所以会报错504 GateWay Time-out超时等。
解决方案:将被调用的项目php-cgi端口改为9001,并开启该端口后再调用就可以了。注意,开启窗口不要关闭哦
开启方式:cmd下::
D:\App_self\phpstudy\PHPTutorial\php\php-7.0.-nts\php-cgi.exe -b 127.0.0.1: -c D:\App_self\phpstudy\PHPTutorial\php\php-7.0.-nts\php.ini
upstream curl_com {
server 127.0.0.1:;
}
location ~ \.php(.*)$ {
fastcgi_pass curl_com;
fastcgi_index index.php;
fastcgi_split_path_info ^((?U).+\.php)(/?.+)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
include fastcgi_params;
}
curl附件上传:
注意,如果你需要上传一个文件,只需要把文件路径像一个post变量一样传过去,不过记得在前面加上"@"符号。执行这段脚本应该会得到如下输出
$url = "http://localhost/upload_output.php";
$post_data = array (
"foo" => "bar",
// 要上传的本地文件地址
"upload" => "@C:/wamp/www/abc.jpg"
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
$output = curl_exec($ch);
curl_close($ch);
echo $output;
输出
array(
[upload] => array(
[name] => test . zip
[type] => image / jpeg
[name] => d:\wamp\tmp\php4ccb . jpg
[error] => 0
[size] => 11836
)
)
snoopy实现信息采集及具体实现:
require_once('Snoopy.class.php' );//引入 Snoopy 类
$snoopy =new Snoopy();
$url = 'http://news.163.com/special/00013C0B/gedixw.html';
//$snoopy->fetch($url);//抓取指定的网页
//$snoopy->fetchtext($url); //除去 HTML 标签和其他无关信息
//$snoopy->fetchform($url); //返回抓取的网页上 form 元素
$snoopy->fetchlinks($url); //抓取的网页上的链接
//$snoopy->submit($url,$formvars);//提交表单到$url。$formvars是要传递的变量数组,例:array('user' =>'admin','pwd' => 'admin');
//$snoopy->submittext($url,$formvars);//同submit,只是去除HTML标签和无关信息
//$snoopy->submitlinks($url,$formvars);//返回链接
$data = $snoopy->results;
print_r($data);//打印结果
file_get_contents使用:
$detail = file_get_contents('http://news.163.com/11/0529/14/757S0JGT00014JB5.html');
file_put_contents('curl1.html', $detail);
小记,使用file_get_contents()函数是信息采集中常用的函数但是有些网站为了防止采集采用了一些防范机制,比如判断是否是浏览器访问等,这时使用这个函数就不可靠了。
就像fsockopen这个函数,其实这个函数不仅可以提交数据还可以发送其他header头信息模拟浏览器访问,
用法是打开套接字连接后,将要发送的头信息以属性名: 属性值的格式拼装成字符串,使用fputs(fwrite)函数即可。
跨域、curl、snoopy、file_get_contents()的更多相关文章
- 【转】php通过curl跨域向asp.net服务器上传文件及参数
转:http://blog.sina.com.cn/s/blog_13331dce50102vq32.html 这是一个由php通过调用asp.net接口向asp.net服务器post上传文件及参数并 ...
- PHP-Ajax跨域解决方案
1.先了解下Ajax跨域问题: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "ht ...
- cURL和file_get_contents实现模拟post请求
以前面试时候,面试官问过我后端有没有跨域问题,但是不敢肯定,现在可以肯定的说没有. 不文用php的cURL和file_get_contents方法分别实现后端跨域.本文场景也是在tp5下实现的. 一, ...
- Php—AJAX跨域问题
<?php /** * ajax proxy * ajax跨域解决办法 * @author suconghou <suconghou@126.com> * @version v1. ...
- PHP跨域form提交
因为安全性因素,直接跨域访问是不被允许的. 1.PHP CURL方式 function curlPost($url,$params) { $postData = ''; foreach($params ...
- Ajax跨域:jsonp还是CORS
跨域一般用jsonp,兼容性比较好.CORS是html5最新的XHR第二版本,不支持IE8,IE9,对移动端的支持非常好.但是考虑项目后期这部分会转到同域名下,而且网址不需要支持ie8,ie9,所以我 ...
- AJAX实现跨域的三种方法
由于在工作中需要使用AJAX请求其他域名下的请求,但是会出现拒绝访问的情况,这是因为基于安全的考虑,AJAX只能访问本地的资源,而不能跨域访问. 比如说你的网站域名是aaa.com,想要通过AJAX请 ...
- AJAX实现跨域的三种种方法(代理,JSONP,XHR2)
由于在工作中需要使用AJAX请求其他域名下的请求,但是会出现拒绝访问的情况,这是因为基于安全的考虑,AJAX只能访问本地的资源,而不能跨域访问. 比如说你的网站域名是aaa.com,想要通过AJAX请 ...
- php 之跨域上传图片
因为要将所有上传的图片上传到一台独立的图片服务器上面,js上传时存在跨域问题,网上找到这种,通过php curl方式,将图片重新发送到另外一台服务器上保存,并返回图片路径!这种方式存在一定问题:1,上 ...
随机推荐
- Vue可复用过渡和动态过渡
前面的话 本文将详细介绍Vue可复用过渡和动态过渡 可复用过渡 过渡可以通过 Vue 的组件系统实现复用.要创建一个可复用过渡组件,需要做的就是将 <transition> 或者 < ...
- FTC诉高通垄断案苹果从中受益
据外媒报道,美国当地时间周二,美国联邦贸易委员会(FTC)诉芯片制造商高通公司(Qualcomm)垄断案进入了终结辩论阶段.这意味着,这起审判也进入最后阶段,它可能颠覆高通在智能手机时代取得成功的至关 ...
- 免费开源的会计软件 GnuCash 3.4 发布
导读 GnuCash 3.4已经发布,GnuCash是免费和开源的会计软件.GnuCash开发团队宣布推出GnuCash 3.4,这是3.x稳定版系列的第五版. 变化 在3.3和3.4之间,完成了以下 ...
- Ubuntu18.04下安装Sublime Text3!
这几天安装了Ubuntu18.04,然后在里面安装Sublime Text3,结果各种问题!各种BUG!试了网上各种办法!尼玛!都是坑爹的啊! 最后还是楼主自己解决了…… 废话不多说,直接按顺序执行下 ...
- GCD HDU - 1695 (欧拉 + 容斥)
GCD Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...
- python_sort(key=) 的使用
""" sort() 函数内含有 key 可以指定相关的函数来作为排序依据 比如这里指定每一项的索引为1 的元素作为排序依据 默认是以第一个作为排序依据 "&q ...
- 【AtCoder3611】Tree MST(点分治,最小生成树)
[AtCoder3611]Tree MST(点分治,最小生成树) 题面 AtCoder 洛谷 给定一棵\(n\)个节点的树,现有有一张完全图,两点\(x,y\)之间的边长为\(w[x]+w[y]+di ...
- 计算机网络实验八实验报告——应用Packet Tracer 5.0模拟器工具对WLAN进行配置
计算机网络实验八实验报告 一.实验目的 1.熟练使用Packet Tracer 5.0模拟器: 2.应用Packet Tracer 5.0模拟器工具对WLAN进行配置. 二.实验环境 一台PC机. 模 ...
- 构建SFTP服务
---------------增加sftp-----------------查看openssh的版本# ssh -V使用ssh -V 命令来查看openssh的版本,版本必须大于4.8p1,低于的这个 ...
- 2018 ICPC 焦作网络赛 E.Jiu Yuan Wants to Eat
题意:四个操作,区间加,区间每个数乘,区间的数变成 2^64-1-x,求区间和. 题解:2^64-1-x=(2^64-1)-x 因为模数为2^64,-x%2^64=-1*x%2^64 由负数取模的性质 ...