php抓取网页连接函数(一个老员工探索服务器_get_contents()设置限制)
优采云 发布时间: 2022-01-28 10:13php抓取网页连接函数(一个老员工探索服务器_get_contents()设置限制)
这两天,公司一位客户的旧车系统中的车库无法更新。通过断点打印发现一个方法获取远程网页内容失败,开始怀疑是自定义打包的方法出错了。咨询了老员工后,决定换成file_get_contents()方法。然而神奇的事情发生了,页面刷新成功获取了远程网页的内容,但是经过多次反复测试,发现还是无法获取远程网页的内容……所以根据对于老员工的意思,我探索了服务器对file_get_contents()的响应来设置限制。
首先,检查服务器的 PHP 是否支持访问 URL 对象(例如文件)。通过找到PHP配置文件php.ini,将allow_url_fopen设置为On,即allow_url_fopen = On。但是,经过检查,发现客户端的服务器已经激活了URL形式的fopen封装协议。
接下来继续百度寻找解决服务器限制file_get_contents()的方法。(我才知道程序员不用百度,都是用google翻墙的……具体原因,可能百度查到的大多是无用的信息。我不是天才,请允许我学习翻墙伟大的GFW[GREAT FIRE WALL]。)所以,我找到了一种使用curl代替file_get_contents()的方法,大致如下:
很多作为虚拟主机租用的服务器一般都会禁用一些IO操作,比如file_get_contents、fsockopen等,因为他们害怕DDOS。但是很多站长需要使用这个功能来抓取URL页面的内容。比如我需要爬取各大网站UED博客中的RSS内容,输出到我的首页。一般情况下,我们不能改变服务器的inc.php,只能写一套IO来代替上面的PHP函数。
$url = file_get_contents('http://www.chongqingwangzhai.com/');
我们可以改用下面的代码
//禁用file_get_contents的解决办法
$ch = curl_init();
$timeout = 10; // set to zero for no timeout
curl_setopt ($ch, CURLOPT_URL,'http://www.chongqingwangzhai.com/');
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
$url = curl_exec($ch);
curl 是一个使用 URL 语法传输文件和数据的工具。它支持多种协议,如HTTP、FTP、TELNET等。它不会被服务器禁用,所以我们可以用它来模拟file_get_contents打开一个URL。
一般我们需要抓取页面数据,比如新浪微博、百度论坛等页面,都需要登录才能进入列表页面,所以这时候需要使用curl来模拟登录,然后打开网址。原理是利用curl设置http访问的头信息,模拟登录的头信息,让对方服务器认为你处于登录状态。具体实现方法就不说了,网上有很多。
(参考网址:)
但是按照上面的方法更换后,结果还是失败了!
后来怀疑是服务器防火墙限制。偶尔ping一下相关的URL,会发现有些ping不通。据了解,可能是服务器的DNS解析有问题。网上有网友提到,修改/etc/hosts文件即可解决问题。不过,我还是先了解hosts文件及其作用:
/etc/hosts、主机名和 ip 配置文件。
hosts - 主机名的静态表查找
我们知道,要在网络上访问网站,首先要通过DNS服务器将网络域名()解析成XXX.XXX.XXX.XXX的IP地址,然后我们的电脑才能访问。如果每次域名请求都要等待域名服务器解析并返回IP信息,访问网络的效率就会降低,而Hosts文件可以提高解析效率。根据Windows系统的规则,在发起DNS请求之前,Windows系统会先检查自己的Hosts文件中是否有地址映射关系,如果有则调用IP地址映射,如果没有已知的DNS服务器,它会提出域名解析。也就是说Hosts的请求级别比DNS高。
因此,我们可以通过提前在Hosts文件中配置相应的地址映射关系来实现一系列的效果。例如:1、加速域名解析;2、方便局域网用户;3、blocks网站;4、顺利连接系统;等等。
(参考网址:)
(参考网址:)
按照上面的方法,我将远程车库(目标服务器)的IP地址等信息配置到客户端服务器的Hosts文件中,刷新网站,再次点击测试功能。
远程网页内容获取成功!!!
经过多次刷新测试,系统仍能正常获取远程网页内容!至此,“无法通过PHP下的file_get_contents()方法正常获取远程网页内容”的问题已经基本解决。