3

我想知道如何在循环中抓取(第 1 页第 2 页等......)一个具有无限循环(如 imgur)的网页,例如......?

我尝试了下面的代码,但它只返回第一页。由于无限滚动模板,如何触发下一页?

<?php
    $mr = $maxredirect === null ? 10 : intval($maxredirect);
    if (ini_get('open_basedir') == '' && ini_get('safe_mode' == 'Off')) {
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, $mr > 0);
        curl_setopt($ch, CURLOPT_MAXREDIRS, $mr);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    } else {
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);

        if ($mr > 0) {
            $original_url = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
            $newurl = $original_url;
            $rch = curl_copy_handle($ch);

            curl_setopt($rch, CURLOPT_HEADER, true);
            curl_setopt($rch, CURLOPT_NOBODY, true);
            curl_setopt($rch, CURLOPT_FORBID_REUSE, false);
            do {
                curl_setopt($rch, CURLOPT_URL, $newurl);
                $header = curl_exec($rch);
                if (curl_errno($rch)) {
                    $code = 0;
                } else {
                    $code = curl_getinfo($rch, CURLINFO_HTTP_CODE);
                    if ($code == 301 || $code == 302) {
                        preg_match('/Location:(.*?)\n/', $header, $matches);
                        $newurl = trim(array_pop($matches));

                        // if no scheme is present then the new url is a
                        // relative path and thus needs some extra care
                        if(!preg_match("/^https?:/i", $newurl)){
                            $newurl = $original_url . $newurl;
                        }
                    } else {
                        $code = 0;
                    }
                }
            } while ($code && --$mr);
            curl_close($rch);
            if (!$mr) {
                if ($maxredirect === null)
                    trigger_error('Too many redirects.', E_USER_WARNING);
                else
                    $maxredirect = 0;
                return false;
            }
            curl_setopt($ch, CURLOPT_URL, $newurl);
        }
    }
    return curl_exec($ch);
}

$ch = curl_init('http://www.imgur.com');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec_follow($ch);
curl_close($ch);

echo $data;
?>
4

2 回答 2

2

cURL通过获取网页的源代码来工作。您的代码将仅从原始网页收集 HTML。在 imgur 的情况下,它将包括约 40 张图像,以及页面布局的其余部分。

向下滚动时,此原始源代码不会更改。但是,浏览器中的 HTML 可以。这是通过 AJAX 完成的。您正在查看的页面从第二个页面请求信息。

如果您使用 FireBug(用于 FireFox)或 Google Chrome 的页面检查器,那么您可以通过转到“网络”或“网络”选项卡(分别)来监控这些请求。当您向下滚动时,页面将再发出约 45 个请求(主要是图像)。您还将看到它请求此页面:

http://imgur.com/gallery/hot/viral/day/page/0?scrolled&set=1

The JavaScript on the imgur homepage appends this HTML to the bottom of the home page. You would probably want to query this page (or the API, as the other Chris said) if you want to get a list of images. You can play with the numbers at the end of the URL to get more images.

于 2013-01-24T20:03:51.967 回答
0

由于类似的原因,页面抓取很少是最好的方法。Imgur 提供了一个 API,它可以完成我假设您正在尝试的任务,而无需使用任何 hacky 抓取。

如果你接受了刮擦的想法,你将不得不做一些研究。您需要注意 AJAX 请求使用的 API,而不是只抓取主页,您可以直接调用该 API 并继续抓取后续页面的数据。这种方法的细节超出了这个答案的范围,特别是考虑到有一个已建立的 API 可用。

相关阅读

于 2013-01-24T19:53:22.317 回答