php我的抓取器在一段时间后出现故障分段错误

时间:2014-08-29 22:39:29

标签: php linux

我是PHP的新手,我知道我在PHP中构建了一个脚本,但过了一段时间它就崩溃了。 我在5-6种不同的Linux操作系统,debian,ubuntu,redhat,fedora等上测试过它。只有在fedora上没有崩溃但是在工作3-4小时后他停下来并且不给我任何错误。这个过程仍然是开放的,他不会崩溃,只是停止工作,但这只在fedora上。

这是我的脚本代码:

<?

ini_set('max_execution_time', 0);
include_once('simple_html_dom.php');

$file = fopen("t.txt", "r");
while(!feof($file)) {
    $line = fgets($file);
    $line = trim($line);
    $line = crawler($line);
}
fclose($file);

function crawler($line) {
    $site = $line;
    // Check target.
    $agent = "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_8; pt-pt) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27";
    $ch=curl_init();
    curl_setopt ($ch, CURLOPT_URL,$line);
    curl_setopt($ch, CURLOPT_USERAGENT, $agent);
    curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt ($ch,CURLOPT_VERBOSE,false);
    curl_setopt($ch, CURLOPT_TIMEOUT, 5);
    curl_exec($ch);
    $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    if($httpcode>=200 && $httpcode<=300) {

        $check2 = $html = @file_get_html($site);
        if($check2 === false) {
            return $line;
        } else {
            foreach($html->find('a') as $element) {
                $checkurl = parse_url($element->href);
                $checkline = parse_url($line);
                if(isset($checkurl['scheme'], $checkurl['host'])) {
                    if($checkurl['host'] !== $checkline['host']) {
                        $split = str_split($checkurl['host']);
                        $replacethis = ".";
                        $replacewith = "dot";

                        for($i=0;$i<count($split);$i++) {
                           if($split[$i] == $replacethis) {
                           $split[$i] = $replacewith;
                           }
                        }
                        chdir('C:\xampp\htdocs\_test\db');
                        foreach($split as $element2) {
                            if(!chdir($element2)) { mkdir($element2); chdir($element2); };
                        }
                        $save = fopen('results.txt', 'a'); $txt = "$line,$element->innertext\n"; fwrite($save,$txt); fclose($save);
                    }
                }
            }
        }
    }
}

?>

因此,我的脚本会抓取我在t.txt中指定的目标的所有反向链接,但只覆盖传出的反向链接...然后他会扩展目录并保存信息。

以下是我遇到的错误:

Allowed memory size of 16777216 bytes exhausted (tried to allocate 24 bytes)
Segmentation fault (core dumped)

似乎某处是一个错误......出了点问题......任何想法?感谢。

1 个答案:

答案 0 :(得分:0)

当你没有空闲内存时,可能会抛出这样的错误。我相信它发生在你的simple_html_dom中。你需要使用

void clear ()   Clean up memory.

根据its documentation

在循环中使用它

此外,您还为每一行执行两个http请求。但这只是一个卷曲请求就足够了。只需保存回复

$html = curl_exec($ch);

而不是使用str_get_html($html)代替file_get_html($site);

使用错误抑制运算符@也是不好的做法。如果它可以抛出异常,你最好通过try ... catch构造来处理它。

此外,您不需要做这样的事情

$site = $line;

只需使用$line

最后代替您的长行$save = fopen('results.txt', 'a');...............,您可以使用简单的file_put_contents()

我建议你输出控制台你现在实际做的事情。喜欢

echo "getting HTML from URL ".$line
echo "parsing text..."

所以你可以以某种方式控制过程