网页抓取程序
1.
http协议
HTTP既可以使用非持久连接(nonpersistent connection),
也可以使用持久连接(persistent connection)。HTTP/1.0使用非持久连接,HTTP/1.1默认使用持久连接。
请求的头部
GET /somedir/page.html HTTP/1.1
Host:www.chinaitlab.com
Connection:close
User-agent:Mozilla/4.0
Accept-language:zh-cn
(额外的回车符和换行符)
响应的头部
HTTP/1.1 200 0K
Connectlon:close
Date: Thu, 13 Oct 2005 03:17:33 GMT
Server: Apache/2.0.54 (Unix)
Last—Nodified:Mon,22 Jun 1998 09;23;24 GMT
Content—Length:6822
Content—Type:text/html
(数据 数据 数据 数据 数据…………)
2.抓取的过程
(1)准备工作
所要抓取的数据有两种情况,1是get,页面链接,2是post,表单提交请求
a.分析结果页面,找出我们所要获取的数据部分出现的规律。
b.分析所要抓取的网页的表单,分析表单的具体项。
c.分析连接的规律,用file_get_contents获取网页内容。
d.建立数据表存放结果,或者直接将获取的结果存成文本格式。
(2) 步骤
a.将结果页面存到本地,用frontpage,dreamweaver,editplus分析结果数据的格式。
b.根据分析的结果编写转化程序 bridge.php.
c.分析查询form的html源代码,找出所有的form项。
d.编写socket程序fget.php,循环抓取数据。
3.一个简单的程序
本程序用来抓取邮编信息
地址:http://www.xeasy.net/epostsearch.php
分析结果页面,发现
<font color=red>结果</font>
post.html
bridge.php
<?php
require_once("iecho.php");
$nvfile="post.html";
$data=file_get_contents ( $nvfile );
$reg = "#<font color=red>([^>]*)</font>#s";
preg_match_all($reg,$data,$matches);
prt($matches); //这就是我们获取的结果。类似于
//------------------
//这里加上转化的代码
?>
分析表单
<form name=postsearch method=POST action=/epostsearch.php><td align=center height=28>
请输入六位的邮政编码:<input name=postcode type=text size=16 maxlength=6 value=200000>
<input type=submit name=postsearch value=立即查询>
</td>
</form>
只有一个postcode项。
fget.php
<?php
/*
需要注意:
1.form的数据必须用rawurlencode编码联起来。
2.必须提交content-length长度
3.post表单的数据必须跟在\r\n\r\n后面。
*/
$v="上海";
$post = rawurlencode('postcode')."=".rawurlencode($v);
$len = strlen($post);
//发送
$host = "www.xeasy.net";
$file = "/epostsearch.php";
$fp = @fsockopen( $host , 80, $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)\n";
} else {
$receive = '';
$out = "POST $file HTTP/1.1\r\n";
$out .= "Host: $host\r\n";
$out .= "Content-type: application/x-www-form-urlencoded\r\n";
$out .= "Connection: Close\r\n";
$out .= "Content-Length: $len\r\n";
$out .="\r\n";
$out .= $post."\r\n";
fwrite($fp, $out);
while (!feof($fp)) {
$receive .= fgets($fp, 128);
}
fclose($fp);
}
echo $receive;
?>