使用PHP的通用网站爬虫

时间:2014-01-02 05:30:47

标签: javascript php jquery html iframe

我想使用PHP创建一个通用网站抓取工具。

通过使用我的Web应用程序,用户将输入任何URL,将提供他需要从给定站点获取的内容的输入,并将单击“开始”按钮。

然后我的网络应用程序将开始从源网站获取数据。

我在iframe中加载页面并使用jQuery我从用户那里得到类和标签特定区域的名称。

但是当我加载ebay或亚马逊等外部网站时它不起作用,因为这些网站受到限制。有没有办法解决这个问题,所以我可以在iFrame中加载任何网站?或者有什么替代我想要实现的目标?

我实际上受到了mozenda的启发,这是一个用.NET开发的软件http://www.mozenda.com/video01-overview/

他们在浏览器控件中加载一个网站,这几乎是一样的。

3 个答案:

答案 0 :(得分:2)

如果目标网站返回"X-Frame-Options: SAMEORIGIN"响应标头,则无法在客户端抓取网站(请参阅问题评论中的@ mc10重复链接)。您必须使用服务器端功能对目标站点进行爬网。

如果wget具有您需要的所有选项,则以下解决方案可能适用。 wget -r将递归抓取网站并下载文档。它有许多有用的选项,比如将绝对嵌入式URL转换为相对的本地URL。

注意: wget必须安装在您的系统中才能生效。我不知道你在运行哪个操作系统,但在Ubuntu上,安装wget是sudo apt-get install wget

请参阅: wget --help了解其他选项。

<?php

    $website_url = $_GET['user_input_url'];

    //doesn't work for ipv6 addresses
    //http://php.net/manual/en/function.filter-var.php
    if( filter_var($website_url, FILTER_VALIDATE_URL) !== false ){

        $command = "wget -r " + escapeshellarg( $website_url );
        system( $command );

        //iterate through downloaded files and folders

    }else{
        //handle invalid url        

    }

答案 1 :(得分:1)

看看在PHP中使用file_get_contents函数。

您可以更好地检索给定网站的HTML,如下所示:

$html = file_get_contents('http://www.ebay.com');

答案 2 :(得分:1)

您可以在以下脚本中的第二个foreach循环中查找您要查找的元素。因为脚本将收集cnn主页上的前100个链接,并将它们放在名为“cnnLinks.txt”的文本文件中,该文件位于该文件所在的文件夹中。

只需将$ pre,$ base和$ post变量更改为您要抓取的任何网址!我将它们分开,以便更快地通过常见网站进行更改。

<?php
    set_time_limit(0);
    $pre = "http://www.";
    $base = "cnn";
    $post = ".com";
    $domain = $pre.$base.$post;
    $content = "google-analytics.com/ga.js";
    $content_tag = "script";
    $output_file = "cnnLinks.txt";
    $max_urls_to_check = 100;
    $rounds = 0;
    $domain_stack = array();
    $max_size_domain_stack = 1000;
    $checked_domains = array();
    while ($domain != "" && $rounds < $max_urls_to_check) {
        $doc = new DOMDocument();
        @$doc->loadHTMLFile($domain);
        $found = false;
        foreach($doc->getElementsByTagName($content_tag) as $tag) {
            if (strpos($tag->nodeValue, $content)) {
                $found = true;
                break;
            }
        }
        $checked_domains[$domain] = $found;
        foreach($doc->getElementsByTagName('a') as $link) {
            $href = $link->getAttribute('href');
            if (strpos($href, 'http://') !== false && strpos($href, $domain) === false) {
                $href_array = explode("/", $href);
                if (count($domain_stack) < $max_size_domain_stack &&
                    $checked_domains["http://".$href_array[2]] === null) {
                    array_push($domain_stack, "http://".$href_array[2]);
                }
            };
        }
        $domain_stack = array_unique($domain_stack);
        $domain = $domain_stack[0];
        unset($domain_stack[0]);
        $domain_stack = array_values($domain_stack);
        $rounds++;
    }

    $found_domains = "";
    foreach ($checked_domains as $key => $value) {
        if ($value) {
            $found_domains .= $key."\n";
        }
    }
    file_put_contents($output_file, $found_domains);
?>