下面是我用fsockopen写的获取网页源代码的类当中的一个get()函数,但是有时候获取网页源代码的时候会失败,刷新几次就会好的,所以我用了for($i=0;$i<3;$i++)这个循环来重试3次,但感觉有时候还是获取失败,请问大家是什么原因啊?应当在哪个地方重试啊? function get($url,$cookie="",$refer="",$code_r="",$jump=1,$timeout=30)
{
$this->parseUrl($url);

for($i=0;$i<3;$i++)
{
$fp = @fsockopen($this->host,$this->port,$errno,$errstr,$timeout);
if($fp) break;
}
if (!$fp) die("sockt错误: {$errno} - {$errstr}");//这句话在无人值守的时候需要注意了
fputs($fp, sprintf("GET %s%s%s HTTP/1.1\r\n", $this->path, $this->query ? "?" : "", $this->query));
fputs($fp, "Host: {$this->host}\r\n");
if($cookie){$this->addCookie($cookie);}
fputs($fp, "Cookie: " . $this->getCookie() . "\r\n");
foreach($this->headers as $key=>$val) {fputs($fp, "{$key}: {$val}\r\n");}
fputs($fp, "\r\n");
return $this->getResult($fp);
} function getResult(&$fp)
{
$result = "";
$header = "";
$inheader = 1;
while(!feof($fp))
{
$line = fgets($fp,1024);
if($inheader && ($line == "\n" || $line == "\r\n"))
{
$inheader = 0;
}
elseif(!$inheader)
{
$result .= $line;
}
else
{
$header .= $line;
}
}
$this->putCookie($header);
if(preg_match("/HTTP\/\d\.\d (301|302) /is",$header,$match))
{
if(preg_match("/Location: ([^\s]+)/is",$header,$match))
{
echo $match[1];
}
}
$result = $this->header ? $header . $result : $result;
return $result;
}

解决方案 »

  1.   

    思路不对,抓取网页最好别用socket自己实现,要处理的细节太多,
    服务器发一个Location: xxx指示跳转,也有可能分段传输,
    这些东西全部自己处理会非常麻烦,而且没有必要,
    socket抓包能做的事情, curl_xxx函数基本都能做,
    cookie/referer/user-agent/host/...,
    这些抓页面时常用到的http-headers在curl里都能处理的很好.连file_get_contents这样的函数都能填写自己的header进去,
    何必用socket做那么麻烦的事情,达成的效果反正是一样的。
      

  2.   

    有时能获取,有时不能,觉得是网络问题。
    我以前做过,经常对一个网站进行连接,网站会kill你的。