【问题标题】:HTTPS link fetch issueHTTPS 链接获取问题
【发布时间】:2012-01-12 19:46:59
【问题描述】:

过去几天我一直在尝试从网站获取请求,但没有成功。 我不断收到错误 301。 有没有人可以帮我抓取这个页面的内容:https://pre.corrupt-net.org/search.php?search=Lasse_Stefanz-Bara_Du-SE-CD-FLAC-1995-LoKET

期待您的回复。

编辑: 这是我用过的php函数:

function http_request(
    $verb = 'GET',             /* HTTP Request Method (GET and POST supported) */
    $ip,                       /* Target IP/Hostname */
    $port = 80,                /* Target TCP port */
    $uri = '/',                /* Target URI */
    $getdata = array(),        /* HTTP GET Data ie. array('var1' => 'val1', 'var2' => 'val2') */
    $postdata = array(),       /* HTTP POST Data ie. array('var1' => 'val1', 'var2' => 'val2') */
    $cookie = array(),         /* HTTP Cookie Data ie. array('var1' => 'val1', 'var2' => 'val2') */
    $custom_headers = array(), /* Custom HTTP headers ie. array('Referer: http://localhost/ */
    $timeout = 1000,           /* Socket timeout in milliseconds */
    $req_hdr = false,          /* Include HTTP request headers */
    $res_hdr = false           /* Include HTTP response headers */
    )
{
    $ret = '';
    $verb = strtoupper($verb);
    $cookie_str = '';
    $getdata_str = count($getdata) ? '?' : '';
    $postdata_str = '';
    foreach ($getdata as $k => $v)
        $getdata_str .= urlencode($k) .'='. urlencode($v);
    foreach ($postdata as $k => $v)
        $postdata_str .= urlencode($k) .'='. urlencode($v) .'&';
    foreach ($cookie as $k => $v)
        $cookie_str .= urlencode($k) .'='. urlencode($v) .'; ';
    $crlf = "\r\n";
    $req = $verb .' '. $uri . $getdata_str .' HTTP/1.1' . $crlf;
    $req .= 'Host: '. $ip . $crlf;
    $req .= 'User-Agent: Mozilla/5.0 Firefox/3.6.12' . $crlf;
    $req .= 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' . $crlf;
    $req .= 'Accept-Language: en-us,en;q=0.5' . $crlf;
    $req .= 'Accept-Encoding: deflate' . $crlf;
    $req .= 'Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7' . $crlf;
    foreach ($custom_headers as $k => $v)
        $req .= $k .': '. $v . $crlf;
    if (!empty($cookie_str))
        $req .= 'Cookie: '. substr($cookie_str, 0, -2) . $crlf;
    if ($verb == 'POST' && !empty($postdata_str)){
        $postdata_str = substr($postdata_str, 0, -1);
        $req .= 'Content-Type: application/x-www-form-urlencoded' . $crlf;
        $req .= 'Content-Length: '. strlen($postdata_str) . $crlf . $crlf;
        $req .= $postdata_str;
    }   
    else $req .= $crlf;
    if ($req_hdr)
        $ret .= $req;
    if (($fp = @fsockopen($ip, $port, $errno, $errstr)) == false)
        return "Error $errno: $errstr\n";
    stream_set_timeout($fp, 0, $timeout * 1000);
    fputs($fp, $req);
    while ($line = fgets($fp)) $ret .= $line;
    fclose($fp);
    if (!$res_hdr)
        $ret = substr($ret, strpos($ret, "\r\n\r\n") + 4);
    return $ret;
}

【问题讨论】:

  • 为什么不简单地使用 curl 之类的东西?

标签: php https request http-status-code-301


【解决方案1】:

首先,301 is not an "error" as such,它表示你正在被重定向。您需要解析响应标头,获取 Location: 标头的值(HTTP 协议规范要求重定向响应中存在该标头)并请求该 URI。

其次,上面的函数似乎不支持访问 HTTPS URL。您需要为您的 PHP 实例安装 OpenSSL 扩展来执行此操作,并且您还需要实际调用它。您可以通过在$ip 参数中的地址前面传递ssl://tls:// 来使用上述函数,但不能简单地传递IP。

第三,执行此类操作的常用方法是使用 cURL 扩展名。你会做这样的事情:

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://pre.corrupt-net.org/search.php?search=Lasse_Stefanz-Bara_Du-SE-CD-FLAC-1995-LoKET'); // Set the URL
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE); // Follow redirects
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); // Get the result from the execution

if (($result = curl_exec($ch)) === FALSE) { // Execute the request
  echo "cURL failed! Error: ".curl_error($ch);
} else {
  echo "Success! Result: $result";
}

curl_close($ch);

或者,如果 cURL 不可用或者您出于某种原因不想使用它,您可以使用my HTTPRequest class,它符合 PHP4 并且不需要扩展(除了用于 HTTPS 请求的 OpenSSL)。在脚本顶部的 cmets 中记录(ish)。你会做这样的事情:

$request = new httprequest(); // Create an object

// Set the request URL
if (!$request->setRequestURL('https://pre.corrupt-net.org/search.php?search=Lasse_Stefanz-Bara_Du-SE-CD-FLAC-1995-LoKET')) echo "Failed! Error: ".$request->getLastErrorStr()."<br>\r\n";
// Send the request
if (!$request->sendRequest()) echo "Failed! Error: ".$request->getLastErrorStr()."<br>\r\n";

echo "Success! Result: ".$request->getResponseBodyData(TRUE);

附带说明,很多 Scene PreDB 管理器/提供者不太热衷于自动抓取,您可能会被禁止...

【讨论】:

  • 感谢您的回复。我已经尝试过您的 curl 代码,尝试发送所有标头,但仍然没有响应。我得到了 Success 但响应变量为空。我将发布您发布的课程的反馈。编辑:我使用 curl 和 httprequest 得到相同的结果。这很奇怪,因为我可以使用标准方式获取文件 lastpred.php: $string = file_get_contents("pre.corrupt-net.org/lastpred.php");
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-17
  • 1970-01-01
相关资源
最近更新 更多