【问题标题】:cant set Host in CURL PHP无法在 CURL PHP 中设置主机
【发布时间】:2015-06-03 06:51:09
【问题描述】:

我无法将主机设置为 curl。如果我使用以下代码,它仍然显示为 localhost

function wget($url)
        {

            $agent= 'Mozilla/5.0 (Windows NT 6.3; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0.1';
            $curlHeaders = array (
                    'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
                    'Accept-Encoding: gzip, deflate',
                    'Accept-Language: en-US,en;q=0.5',
                    'User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0.1',
                    'Connection: Keep-Alive',
                    'Pragma: no-cache',
                    'Referer: http://example.com/',
                    'Host: hostname',
                    'Cache-Control: no-cache',
                    'Cookie: visid_incap_185989=9v1q8Ar0ToSOja48BRmb8nn1GFUAAAAAQUIPAAAAAABCRWagbDIfmlN9NTrcvrct; incap_ses_108_185989=Z1orY6Bd0z3nGYE2lbJ/AXn1GFUAAAAAmb41m+jMLFCJB1rTIF28Mg==; _ga=GA1.3.637468927.1427699070; _gat=1; frontend=rqg7g9hp2ht788l309m7gk8qi7; _gat_UA-1279175-12=1; __utma=233911437.637468927.1427699070.1427699078.1427699078.1; __utmb=233911437.2.10.1427699078; __utmc=233911437; __utmz=233911437.1427699078.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utmt_UA-1279175-1=1; _cb_ls=1; _chartbeat2=S0WVXDwMWnCFBgQp.1427699081322.1427699232786.1; PRUM_EPISODES=s=1427699568560&r=http%3A//example.com/'

            );
            $ch = curl_init();
            curl_setopt ($ch, CURLOPT_HTTPHEADER, $curlHeaders);
            curl_setopt ($ch, CURLOPT_HEADER, TRUE);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_USERAGENT, $agent);
            curl_setopt($ch, CURLOPT_URL,$url);
            $result=curl_exec($ch);
            return $result;
        }

我使用fiddler 来跟踪网络请求。我发现主机仍然是 localhost

如果我在浏览器中加载相同的链接,我会在fiddler 中得到以下信息

我需要访问我指定的域。我怎样才能做到这一点? 注意:我知道主机名不应包含协议。

或者

我也想知道是否可以通过终端在浏览器中看到网站的源代码?

【问题讨论】:

  • 我建议先将curl_setopt($ch, CURLOPT_VERBOSE, true); 添加到您的代码中,然后检查后台实际发生的情况。你可能会得到比 fiddler 更多的信息。
  • 我试过你的代码。其他文件接收头Host: hostname。我认为您需要像我的网站一样将其屏蔽为“stackoverflow.com”,这很难做到。您可以修改标头,但不能修改 HTTP 协议(​​不容易做到)。
  • 所以我通过将 url 提供给函数调用,在我可以访问的几台主机上运行它,它运行完美。您需要检查一些事情并提供更多信息。 1)该URL如何输入函数调用,您确定它设置正确吗? IE。如果你调用 $result = wget($someurl);确保 $someurl 设置正确。 2) 检查您的主机文件和代理设置。
  • 将完整的 URL 设置为 CURLOPT_URL。

标签: php curl web-scraping web-crawler


【解决方案1】:

假设我们没有尝试欺骗 Host 标头,完全省略 Host 标头并让 curl 对其进行排序。在这种情况下,只需删除 'Host: hostname',,因为您已经使用 curl 自动设置此设置,代码靠近底部的 curl_setopt($ch, CURLOPT_URL, $url);

如果您真的想自己设置Host 标头,那么只需替换

'Host: hostname',

"Host: ". parse_url($url, PHP_URL_HOST),

(注意:此功能不适用于相对 URL。)

【讨论】:

    【解决方案2】:

    试试这样,

      curl_init('XXX.XXX.XXX.XXX');
      curl_setopt($ch, CURLOPT_HTTPHEADER, array('Host: subdomain.hostname.com'));
    

    【讨论】:

    • 试试这样,$ipaddress='desired_ip'; $url='路径/到/文件?'; curl_init('http://'.$ipaddress.$url);
    • 我正在使用 windows 和 xampp.. 会有什么问题吗?
    • 如果通过此代码发送单个请求,然后当我尝试在浏览器中加载此页面时,它会要求验证码
    【解决方案3】:

    如果您使用的是 windows 和 xampp,请尝试使用 虚拟主机 而不是 localhost,然后它将开始工作,我也是这样做的。

    【讨论】:

    • 如何使用虚拟主机
    【解决方案4】:

    根据HTTP 快速规范阅读,我认为您的问题是由于发送了不正确的Host 标头而发生的。我可以使用以下代码下载一些网站:

    function wget($url, $follow = true) {
    
        $host = parse_url($url);
    
        $agent       = 'Mozilla/5.0 (Windows NT 6.3; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0.1';
        $curlHeaders = array(
            'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
            'Accept-Encoding: gzip, deflate',
            'Accept-Language: en-US,en;q=0.5',
            'User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0.1',
            'Connection: Keep-Alive',
            'Pragma: no-cache',
            'Referer: http://example.com/',
            'Host: ' . $host['host'] . (isset($host['port']) ? ':' . $host['port'] : null), // building host header
            'Cache-Control: no-cache',
            'Cookie: visid_incap_185989=9v1q8Ar0ToSOja48BRmb8nn1GFUAAAAAQUIPAAAAAABCRWagbDIfmlN9NTrcvrct; incap_ses_108_185989=Z1orY6Bd0z3nGYE2lbJ/AXn1GFUAAAAAmb41m+jMLFCJB1rTIF28Mg==; _ga=GA1.3.637468927.1427699070; _gat=1; frontend=rqg7g9hp2ht788l309m7gk8qi7; _gat_UA-1279175-12=1; __utma=233911437.637468927.1427699070.1427699078.1427699078.1; __utmb=233911437.2.10.1427699078; __utmc=233911437; __utmz=233911437.1427699078.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utmt_UA-1279175-1=1; _cb_ls=1; _chartbeat2=S0WVXDwMWnCFBgQp.1427699081322.1427699232786.1; PRUM_EPISODES=s=1427699568560&r=http%3A//example.com/'
        );
        $ch          = curl_init();
        curl_setopt($ch, CURLOPT_HTTPHEADER, $curlHeaders);
        curl_setopt($ch, CURLOPT_HEADER, TRUE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, $follow); // following redirects or not
        curl_setopt($ch, CURLOPT_USERAGENT, $agent);
        curl_setopt($ch, CURLOPT_URL, $url);
        $result      = curl_exec($ch);
        return $result;
    }
    
    echo(wget('http://example.com'));
    

    无论如何,此功能不是通用构建。就我个人而言,我会在重定向请求等之间添加保存 cookie。基本更改在“主机”标题行中。我正在那里构建适当的 Host 标头,基于提供给功能的完整 $url

    【讨论】:

    • 我发现我试图抓取的网站正在使用 JS 来验证/验证请求是否是通过浏览器发送的。如果它用浏览器打开,主机是 example.com,它会加载一个文件example.com/verify.js。因此,如果请求是通过浏览器发送的,它会为localhost/verify.js 加载。在此之前,上面的代码返回一个我可以在浏览器的检查元素中看到的 javascript。
    • @DharanBro 很不理解你的评论。它工作正常还是仍有一些问题?
    【解决方案5】:

    将完整的 URL 设置为 CURLOPT_URL。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-02-05
      • 2016-04-13
      • 2020-05-01
      • 2013-06-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多