php curl 登录 espn.com

php curl login to espn.com

为了使用 cUrl 登录 http://www.espn.com/login/ and after login i want to retrieve a protected password area http://games.espn.com/ffl/clubhouse?leagueId=93772&teamId=1&seasonId=2018

,我尝试了很多不同的方法,但没有找到任何解决方案

我尝试使用的是:

$username = 'email';
$password = 'password!';
$loginUrl = 'http://www.espn.com/login/';

//init curl
$ch = curl_init();

//Set the URL to work with
curl_setopt($ch, CURLOPT_URL, $loginUrl);

// ENABLE HTTP POST
curl_setopt($ch, CURLOPT_POST, 1);

//Set the post parameters
curl_setopt($ch, CURLOPT_POSTFIELDS, 'user='.$username.'&pass='.$password);

//Handle cookies for the login
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt');

//Setting CURLOPT_RETURNTRANSFER variable to 1 will force cURL
//not to print out the results of its query.
//Instead, it will return the results as a string return value
//from curl_exec() instead of the usual true/false.
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

//execute the request (the login)
$store = curl_exec($ch);

//the login is now done and you can continue to get the
//protected content.
sleep(3);
//set the URL to the protected file
curl_setopt($ch, CURLOPT_URL, 'http://games.espn.com/ffl/clubhouse?leagueId=93772&teamId=1&seasonId=2018');

//execute the request
$content = curl_exec($ch);

curl_close($ch);

//save the data to disk
file_put_contents('download.txt', $content);

但在脚本登录后又没有检索到 html!

这个页面的登录过程 far 比你的代码写的要复杂,而且,这很不寻常,这是我见过的第一个不使用 cookie 的网站登录系统(这是 near-universal 的方式)- 登录方法如下:

1:使用 headers Access-Control-Request-Method: POST and Access-Control-Request-Headers: cache-control,content-type,conversation-id,correlation-id,expires,pragma and Origin: https://cdn.registerdisney.go.comhttps://registerdisney.go.com/jgc/v6/client/ESPN-ONESITE.WEB-PROD/api-key?langPref=en-US 发送 OPTIONS 请求, 它会用一个 header 看起来像 correlation-id: 13fb884f-d873-4344-9f32-fdeaa64cec7c 来响应,你必须解析并保存这个 correlation-id header.

2:这个比较棘手,你需要生成一个conversation-id,我给你提取了生成算法,它隐藏在minified js中很深,它是由uuid函数生成的,如下所示:

function f() { return g() + g() + "-" + g() + "-" + g("4") + "-" + g((Math.floor(10 * Math.random()) % 4 + 8).toString(16)) + "-" + g() + g() + g() }

function g(e) { for (var t = Math.floor(65535 * Math.random()).toString(16), n = 4 - t.length; n > 0; n--) t = "0" + t; return e = ("" + e).substring(0, 4), !isNaN(parseInt(e, 16)) && e.length ? e + t.substr(e.length) : t }

function uuid(){return f();}

(并且因为您是 运行 PHP,而不是 javascript,您必须将此代码转换为 PHP。如果您同时知道这两个 javascript 和 PHP, i cba atm), 输出类似于 conversation-id: e2e3b494-2b67-4fe1-b0a2-21e0f7fa84ff,生成后保存。现在向 https://registerdisney.go.com/jgc/v6/client/ESPN-ONESITE.WEB-PROD/api-key?langPref=en-US 发送 POST 请求,请求 body 字面上包含字符串 null,并且 headers Referer: https://cdn.registerdisney.go.com/v2/ESPN-ONESITE.WEB-PROD/en-US?include=config,l10n,js,html&scheme=http&postMessageOrigin=http%3A%2F%2Fwww.espn.com%2Flogin%2F&cookieDomain=www.espn.com&config=PROD&logLevel=LOG&topHost=www.espn.com&cssOverride=https%3A%2F%2Fsecure.espncdn.com%2Fcombiner%2Fc%3Fcss%3Ddisneyid%2Fcore.css&responderPage=https%3A%2F%2Fwww.espn.com%2Flogin%2Fresponder%2F&buildId=16388ed5943Content-Type: application/jsonconversation-id: $conversation_idcorrelation-id: $correlation_id(请注意,referer-header 是硬编码的和伪造的,您不会重定向到此 url,但 javascript 代码是为了伪造它,让它看起来像是一个重定向。奇怪的狗屎,对吧?)

响应将包含一个 api-key header,看起来像 api-key: MR6UpmRG0VAqAvKStLzof79sbb+1w/HHBextDPqktXf9eXoDfklhgRMFKBpOqt5j63AqoYFx0VHH7/eePYnuw9U7Rg1F,您必须解析并保存此 api 键。

3:使用 headers Access-Control-Request-Method: POSTAccess-Control-Request-Headers: authorization,cache-control,content-type,conversation-id,correlation-id,expires,pragmaOrigin: https://cdn.registerdisney.go.com

https://ha.registerdisney.go.com/jgc/v6/client/ESPN-ONESITE.WEB-PROD/guest/login?langPref=en-US HTTP/1.1 发出 OPTIONS 请求

注意:它会在header中给你一个新的correlation-id令牌,但是忽略它,它似乎没有在任何地方使用,旧的correlation-token是1 你应该继续使用下一个请求。

4:向https://ha.registerdisney.go.com/jgc/v6/client/ESPN-ONESITE.WEB-PROD/guest/login?langPref=en-US发起POST请求,body必须是json-encoded,用户名和密码,看起来像json_encode(array('loginValue'=>$username,'password'=>$password)) ,使用 headers Referer: https://cdn.registerdisney.go.com/v2/ESPN-ONESITE.WEB-PROD/en-US?include=config,l10n,js,html&scheme=http&postMessageOrigin=http%3A%2F%2Fwww.espn.com%2Flogin%2F&cookieDomain=www.espn.com&config=PROD&logLevel=LOG&topHost=www.espn.com&cssOverride=https%3A%2F%2Fsecure.espncdn.com%2Fcombiner%2Fc%3Fcss%3Ddisneyid%2Fcore.css&responderPage=https%3A%2F%2Fwww.espn.com%2Flogin%2Fresponder%2F&buildId=16388ed5943 and Content-Type: application/json and Authorization: APIKEY $api_key(注意,您必须从字面上以大写字符串 APIKEY 开头,后跟 space 和您之前提取的实际 api 密钥)以及 correlation-id: $correlation_idconversation-id: $conversation_id 以及 Origin: https://cdn.registerdisney.go.com

这里是响应了一个json,推测是登录成功,json的error成员为空,但是比如当用户名不存在时存在,错误 object 包含以下内容: Error: invalid_grant, Description: 'PROFILE.NOT_FOUND', Code: AUTHENTICATION_FAILED"}

(表示我使用的用户名 foo 不存在。)

如果现在登录成功,我假设它会为您提供一个令牌或 cookie,您可以将其提供给 http://games.espn.com/ffl/clubhouse?leagueId=93772&teamId=1&seasonId=2018 以检查页面是否已登录,但由于我没有有效的 username/password 进行测试,我实际上无法确认这一点。