You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP cURL爬取特定网站遇连接超时(仅线上服务器),如何解决?

问题描述

我尝试用以下PHP cURL代码爬取特定网站HTML中的h1元素:

<?php
    error_reporting(E_ALL);
    ini_set('display_errors', 1);
    header('Content-Type: text/plain; charset=utf-8');
    header('Access-Control-Allow-Origin: *');
    header('Access-Control-Allow-Methods: POST, GET, OPTIONS');

    if(isset($_POST["url"])){
        $user_agent = "Mozilla/5.0 (Macintosh; 
        Intel Mac OS X 10_14_4) AppleWebKit/537.36 
        (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36"; 
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3600);
        curl_setopt($ch, CURLOPT_TIMEOUT, 3600);
        curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_VERBOSE, true);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_URL,$url);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
        $html=curl_exec($ch);
        if (!curl_errno($ch)){
            $resultStatus = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            if ($resultStatus == 200) {
                @$DOM = new DOMDocument;
                @$DOM->loadHTML('<?xml encoding="UTF-8">' . $html);
                echo $DOM->getElementsByTagName('h1')[0]->textContent;
            }
            else
                echo "Error: ".$resultStatus;
        }
        else
            echo "No h1 found ".curl_error($ch)
    }
?>

目标网址:

https://neindiabroadcast.com/2023/03/24/bharat-gaurav-train-flagged-off-from-guwahati-for-arunachal-pradesh/

但持续收到错误:

No h1 found Failed to connect to neindiabroadcast.com port 443 after 15402 ms: Connection timed out

已将CURLOPT_CONNECTTIMEOUT和CURLOPT_TIMEOUT设置为3600秒,但问题仍存在。且仅线上服务器出现该错误,本地服务器可成功获取数据。

解决方案

1. 修复代码中的变量未定义问题

代码中未将$_POST["url"]赋值给$url变量,导致cURL请求的URL未定义,这是明显的逻辑错误。在if(isset($_POST["url"])){后添加如下代码:

$url = $_POST["url"];

2. 排查线上服务器IP是否被目标网站屏蔽

本地能正常访问但线上不行,大概率是线上服务器的IP被目标网站的反爬机制封禁。可以通过以下方式验证:

  • 登录线上服务器,执行命令测试连接:
    curl -v https://neindiabroadcast.com
    # 或者用telnet测试端口连通性
    telnet neindiabroadcast.com 443
    
    如果命令返回连接超时或拒绝,说明IP被屏蔽。
  • 解决办法:
    • 使用代理IP中转请求,在cURL中添加代理配置:
      curl_setopt($ch, CURLOPT_PROXY, 'http://your-proxy-ip:port');
      // 如果代理需要认证
      curl_setopt($ch, CURLOPT_PROXYUSERPWD, 'username:password');
      
    • 联系服务器提供商更换服务器IP;
    • 使用CDN或云函数中转请求,避免直接用服务器IP访问目标网站。

3. 优化cURL请求头,模拟真实浏览器

目标网站可能会识别非标准请求头并拦截。修改请求头,让请求更贴近真实浏览器:

  • 将换行的User-Agent改为单行:
    $user_agent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36";
    
  • 添加完整的HTTP请求头:
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
        'Accept-Language: en-US,en;q=0.5',
        'Referer: https://neindiabroadcast.com/',
        'DNT: 1',
        'Connection: keep-alive',
        'Upgrade-Insecure-Requests: 1'
    ));
    

4. 检查线上服务器的网络限制

部分服务器提供商可能会限制出站的HTTPS请求,或服务器防火墙规则拦截了对目标网站的访问:

  • 测试线上服务器能否访问其他HTTPS网站(如curl https://google.com),如果也失败,联系服务器提供商排查网络权限;
  • 检查服务器的防火墙配置,确保允许访问目标网站的443端口。

5. 调整cURL的SSL配置

线上服务器的SSL环境可能与本地不同,尝试指定TLS版本并调整验证设置:

// 指定TLS版本(根据目标网站支持的版本选择,通常TLSv1.2或TLSv1.3)
curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
// 开启SSL主机验证(如果IP未被封,严格验证可避免部分SSL错误)
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);

内容的提问来源于stack exchange,提问作者user21506970

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 22:55:02