CURLOPT_POSTFIELDS仅适用于硬编码字符串

时间:2016-10-09 09:36:43

标签: php php-curl

使用curl执行POST请求时遇到一些奇怪的问题。我想抓一个网站获取一些信息。该网站使用ASPX编写。

我正在执行GET请求以获取VIEWSTATE,VIEWSTATEGENERATOR和EVENTVALIDATION值。这段代码工作正常。

$html = $this->hhb_curl_exec2($ch, $this->url, $debugHeaders, $debugCookies, $debugRequest);
$domd = new \DOMDocument();
libxml_use_internal_errors(true);
$domd->loadHTML($html);
assert(is_object($domd));
$__VIEWSTATE = $domd->getElementById('__VIEWSTATE')->getAttribute('value');
$__VIEWSTATEGENERATOR =  $domd->getElementById('__VIEWSTATEGENERATOR')->getAttribute('value');
$__EVENTVALIDATION = $domd->getElementById('__EVENTVALIDATION')->getAttribute('value');

执行POST请求的代码

curl_setopt($ch, CURLOPT_TIMEOUT, 60 );       
curl_setopt($ch, CURLOPT_ENCODING, '' );   
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt($ch, CURLOPT_HTTPHEADER, array ( 'Expect :', 'Content-type: application/x-www-form-urlencoded', 'Connection: keep-alive', 'Accept-Language: en-US,en;q=0.8', 'DNT: 1','Upgrade-Insecure-Requests: 1', 'User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36', ) ) ;
curl_setopt($ch, CURLOPT_POST, true );
curl_setopt($ch, CURLOPT_POSTFIELDS, $data );
$html = $this->hhb_curl_exec2($ch, $this->url, $debugHeaders, $debugCookies, $debugRequest);

我尝试使用以下方法格式化数据以传递到CURLOPT_POSTFIELDS。 - http_build_query - 格式化字符串 这一切都失败了。

但是如果我要回显http_build_query输出并将值硬编码到$ data中,它就可以工作。试图遵循这个逻辑,我尝试将ob_start和ob_get_clean用于变量,但它仍然不起作用。我当时认为它可能与编码有关所以我尝试使用urlencode,rawurlencode等仍然无法正常工作。

已经持续了4天。有人有什么想法吗?

这是我填充到数组中的数据

        $data = [];
        $data['__EVENTTARGET'] = '';
        $data['__EVENTARGUMENT'] = '';
        $data['txtID'] = '123';
        $data['Type'] = 'Check';
        $data['__VIEWSTATE']  = '/wEPDwUKLTgxMjY3NTc3OQ9kFgICAw9kFggCDA9kFgICAw8PFgIeB1Zpc2libGVoZGQCDQ9kFgICAw8PFgIfAGhkZAIOD2QWAgIDDw8WAh8AaGRkAhMPDxYCHgRUZXh0BQM2ODFkZBgBBQhDYXB0Y2hhMQ8FJGU3MWM0NWRkLTc5NTYtNDg1OS05NjBjLThkZGVlMjg5NjRkYWSfOThWHvPz4/TL+UaGirQZ5RboSnTC9dUIpDr5cInhgQ==';
        $data['__VIEWSTATEGENERATOR'] = '259A63A1';
        $data['__EVENTVALIDATION'] = '/wEdAATzTFkZdU/CJ5dXkuY45iU6kpmFQIiHR062LxhkThIrE5l/kxSnaCiVP8n0gK4NzCOkWRDoSjN1G98r+I9h/rD7Tmr9zlIbeGS1P8q5MIlYg1K5J4JlQdGE6eaZgYCE+Ic=';

硬编码的值只是在$ t上使用http_build_query, 我通常得到的是

__EVENTTARGET=&__EVENTARGUMENT=&txtID=123&Type=Check&__VIEWSTATEGENERATOR=259A63A1&__VIEWSTATE=%2FwEPDwUKLTgxMjY3NTc3OQ9kFgICAw9kFggCDA9kFgICAw8PFgIeB1Zpc2libGVoZGQCDQ9kFgICAw8PFgIfAGhkZAIOD2QWAgIDDw8WAh8AaGRkAhMPDxYCHgRUZXh0BQM2ODFkZBgBBQhDYXB0Y2hhMQ8FJGU3MWM0NWRkLTc5NTYtNDg1OS05NjBjLThkZGVlMjg5NjRkYWSfOThWHvPz4%2FTL%2BUaGirQZ5RboSnTC9dUIpDr5cInhgQ%3D%3D&__EVENTVALIDATION=%2FwEdAATzTFkZdU%2FCJ5dXkuY45iU6kpmFQIiHR062LxhkThIrE5l%2FkxSnaCiVP8n0gK4NzCOkWRDoSjN1G98r%2BI9h%2FrD7Tmr9zlIbeGS1P8q5MIlYg1K5J4JlQdGE6eaZgYCE%2BIc%3D

有关正在发生的事情的更详细解释。

如果我使用此方法构建要发布的字符串,它就不起作用,

$ev = urlencode( $__EVENTVALIDATION );
$vs = urlencode( $__VIEWSTATE );

$apc = 'Type=Check&__EVENTARGUMENT=&__EVENTTARGET='.
        "&__EVENTVALIDATION={$ev}".
        "&__VIEWSTATE={$vs}".
        "&__VIEWSTATEGENERATOR={$__VIEWSTATEGENERATOR}&txtID={$id}";

然而,如果我这样做的话,它的确有些奇怪的原因。

$ev = urlencode( '/wEdAATzTFkZdU/CJ5dXkuY45iU6kpmFQIiHR062LxhkThIrE5l/kxSnaCiVP8n0gK4NzCOkWRDoSjN1G98r+I9h/rD7Tmr9zlIbeGS1P8q5MIlYg1K5J4JlQdGE6eaZgYCE+Ic=' );
$vs = urlencode( '/wEPDwUKLTgxMjY3NTc3OQ9kFgICAw9kFggCDA9kFgICAw8PFgIeB1Zpc2libGVoZGQCDQ9kFgICAw8PFgIfAGhkZAIOD2QWAgIDDw8WAh8AaGRkAhMPDxYCHgRUZXh0BQM2ODFkZBgBBQhDYXB0Y2hhMQ8FJGU3MWM0NWRkLTc5NTYtNDg1OS05NjBjLThkZGVlMjg5NjRkYWSfOThWHvPz4/TL+UaGirQZ5RboSnTC9dUIpDr5cInhgQ==' );

$apc = 'Type=Check&__EVENTARGUMENT=&__EVENTTARGET='.
        "&__EVENTVALIDATION={$ev}".
        "&__VIEWSTATE={$vs}".
        "&__VIEWSTATEGENERATOR={$__VIEWSTATEGENERATOR}&txtID={$id}";

1 个答案:

答案 0 :(得分:0)

终于找到了我的问题的真正原因,我正在废弃的网站在服务器端处理了一些额外的检查,并决定不回发错误。

我只需要设置3秒的延迟就可以了。

对不起,伙计们。