PHP编写爬虫遇到的问题

编写了一个爬取豆瓣图书信息到数据库的爬虫,编写过程中遇到许多问题。

写出来作为学习笔记,以及对全部所用到的知识点的总结。

一、PHP脚本最大执行时间 和 最大执行内存

最开始编写的爬虫运行一段时间后总是会终止运行,经过初步排查可能是PHP默认的脚本最大运行的时间和运行内存限制影响。

a. PHP脚本运行最大时间设置

有两种设置方法:一种是永久的更改所有脚本运行时间,另一种是只对当前运行脚本起作用

  1. 修改php.ini配置文件
    max_execution_time = 0; //该方法对所有php脚本都起作用
  2. 通过set_time_limit()函数设置
    在php脚本文件开头加入set_time_limit(0); //只对当前脚本生效
    上述两种方法设置为0都代表无限制

b. PHP脚本运行最大内存设置

同上所述,同样是两种方法,两种作用范围
1. 修改php.ini配置文件
memory_limit = 256M; //该方法对所有php脚本都起作用
2. 通过ini_set();函数设置
在php脚本文件开头加入ini_set(‘memory_limit’, ‘128M’); //只对当前脚本生效

二、PHP缓存机制

在爬虫爬取信息的时候,有一个实时的反馈信息查看当前爬取状态才是较为友好的,也便于出错时进行排查。这个时候就需要了解到php的缓存区机制了。

我们所有在php脚本中进行输出的内容,都会先进入php内部的缓存区,然后在经过后序一系列的,如:系统缓冲区、浏览器缓冲区…等处理后显示给用户。

而php缓冲区输出机制有以下几种:

  1. 当前脚本执行完毕,输出缓冲区内容
  2. 缓冲区达到所设置的最大内存,输出缓冲区内容
  3. 手动输出缓冲区内容3.手动输出缓冲区内容

前两种为脚本正常运行几种,这里我们需要讨论的是手动输出缓冲区内容

<?php
ob_start();		//开启缓冲区
for ($i=0; $i < 100; $i++) { 
   echo $i.'<br/>';
   echo str_repeat(" ", 4096);	//填充字符串
   ob_flush();	//刷新php缓冲区
   flush();	 	//刷新apache缓存区
   sleep(1);
}

这里需要注意的是echo str_repeat(" ", 4096); 这是对PHP的缓冲区进行填充。

由于PHP内部的优化机制,有时候即使手动刷新缓冲区,但是缓存区未达到上限(php.ini中的默认配置output_buffering,默认为4096b)

还需注意ob_flush() 和 flush()的区别。

ob_flush 和 flush的区别

ob_flush是刷新PHP内部的缓冲区的。正如上文所述,我们在PHP脚本中输出的内容,需要经过多个缓冲区,首先是在PHP的缓冲区存储 => 服务器缓冲区 => 浏览器缓冲区 => 输出

ob_*系列的函数都是对PHP的缓冲区进行操作的
flush()函数是对服务器(apache、nginx)的缓冲区进行刷新的

参考:https://www.cnblogs.com/phpper/p/7750104.html

三、PHP curl代理模式设置与使用

1. HTTP请求头信息设置

// 请求头信息
	$headers = array(
		'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
	    'Cookie: ,
		'Upgrade-Insecure-Requests: 1',
		//可在这里添加需要的请求头信息,以一维数组形式
	);
	/ 请求初始化
	$ch  = curl_init();
	curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);	//请求头信息设置

2. 代理ip设置

	curl_setopt($ch, CURLOPT_PROXY, 127.0.0.1);		//代理ip
	curl_setopt($ch, CURLOPT_PROXYPORT, 80); 		//代理服务器端口

3.其他常用curl拓展函数

	// 请求初始化
	$ch  = curl_init();
	curl_setopt($ch, CURLOPT_HEADER, 0);			//是否输出响应头。(1要,0不要)
	curl_setopt($ch, CURLOPT_URL, $url);			//请求地址
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);	//返回信息以字符串输出信息
	curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);//SSL验证(访问HTTPS链接时,需要关闭验证)
	curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 7);	//超时时间
	curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);	//请求头信息设置
	curl_setopt($ch, CURLINFO_HEADER_OUT, 1);		//请求头信息句柄
	curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);	//重定向抓取
	curl_setopt($ch, CURLOPT_PROXY, $proxy);		//代理ip
	curl_setopt($ch, CURLOPT_PROXYPORT, 80); 		//代理服务器端口
	// 返回的信息
	$output = curl_exec($ch);
	$info   = curl_getinfo($ch);	//请求头信息

四、Apache工作模式和最大并发请求数设置

工作模式分别有:beos,event,worker,prefork,mpmt_os2
各个模式的最大并发数设置与操作系统和设置的模式有关(如:单进程多线程、多进程单线程、多进程多线程)

首先,查看当前Apache的工作模式:

  1. 通过 httpd -l 查看Apache当前工作模式
    在这里插入图片描述
    可以看出当前是在winnt工作模式,那么接下来就根据winnt工作模式,对apache的最大并发请求数设置

  2. 在apache目录下的 conf -> extra 中的 httpd-mpm.conf 文件中
    在这里插入图片描述
    找到所对应的winnt工作模式模块,并进行修改
    在这里插入图片描述

注:Apache调优及学习其底层原理还需要很长一段路要走,在这记录一些Apache底层原理的好文章,以供日后学习

链接:
https://www.cnblogs.com/liaokailin/p/3967421.html
http://www.cnblogs.com/liuxuzzz/p/5346700.html
https://blog.csdn.net/davissuperman/article/details/40738507
https://blog.csdn.net/bjash/article/details/50394894

五、PHP爬虫优化

PHP在浏览器上进行爬虫,在爬取200次左右,apache服务器内部总是会报500错误(至今不明白是什么原因)

最开始以为是php缓存和apache并发数的问题,然而换到cmd下运行并不会出现这样的问题(查阅资料,据说是windows操作系统的原因,好像换到linux下就正常。)

==================== 华丽的分割线 ========================

经过在不同浏览器下测试,不同的浏览器在爬取不同次数之后爬虫都会终止运行

由此推测,可能是浏览器问题

把PHP脚本文件换到CMD下运行,解决该问题

猜你喜欢

转载自blog.csdn.net/weixin_43725997/article/details/85055598
今日推荐