抓取网站的有效方式

时间:2013-12-04 17:03:36

标签: php web-crawler

假设有一个分类广告网站,每个产品的唯一网址只是一个数字: example.com/product/12345/现在,我们假设每个数字都会向页面中的其他产品提供结果,并说我希望扫描所有网址,并通过从ex:{{1中提取信息来获取页面中的每个信息现在我试着用

之类的东西来做这件事
<div id='info'>someinfo</div>

即使此脚本以某种方式工作,但由于内存限制,在崩溃我的系统之前,它无法写入超过前5个结果的内容。所以,我想知道这是如何完成的。

我可以使用DOM对象来获取div的内容,但真正的问题是如何不让脚本冻结页面。

这有什么解决方案吗?

2 个答案:

答案 0 :(得分:2)

我建议为这样的抓取工具创建shell脚本。然后你不需要关心超时:

#!/usr/bin/env php
<?php
$url = 1000;
for ($i = 1; $i < $url; ++$i) {
    $content = getContent("http://example.com/products/$i");
    $info = getInfo($content);
    file_put_contents('file.txt', implode("\n", $info), FILE_APPEND);
}

function getContent($url) {
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $data = curl_exec($ch);
    $curl_errno = curl_errno($ch);
    $curl_error = curl_error($ch);
    curl_close($ch);
    $curl_errno === 0 or die("cURL Error ($curl_errno): $curl_error\n");
    //sleep(2); // Pause 2 sec to avoid ban :)
    return $data;
}

function getInfo($content) {
    $doc = new DOMDocument();
    $doc->loadHTML($content);
    $xpath = new DOMXPath($doc);
    $result = array();
    // Adopt this block for your needs. This is just example 
    $elements = $xpath->query("//*[@id='info']");
    foreach ($elements as $element) {
        $result[] = $element->nodeValue;
    }
    return $result;
}

答案 1 :(得分:1)

我还没有能够测试这个,因为在线代码编辑器我使用的不允许我给它$_GET值,但我想这是欺骗PHP运行代码的最简单方法时间限制。 (或类似的东西)

$url = intval($_GET['url']);
if ($url >= 1) {
    $content = file_get_contents("http://example.com/products/$url"); 
    $info = //get the exact info from div and 
    file_put_contents('file.txt', $info);
    ob_end_flush();
    $url--;
    header("Location: ./thisfile.php?url=$url");
}