模拟登录 pixiv.net
注意:本文的方法已作废,新方法在这里
由于 pixivAPI 有一些内容无法获取,于是模拟登录就派上用场辣
旧版登录接口 (https://www.secure.pixiv.net/login.php) 已经作废。目前新版登录页是用 React 渲染的,但是还是为老浏览器用户开启了兼容♂通道,首先找出这段表单代码:
<div id="old-login" style="display: none;">
<form action="/login" method="POST">
<input type="hidden" name="post_key" value="b827a089c8e7209503d23235d2ba4b43">
<input type="hidden" name="return_to" value="http://www.pixiv.net/">
<input type="hidden" name="lang" value="zh">
<input type="hidden" name="source" value="pc">
<div class="input-field-group">
<div class="input-field">
<input type="text" name="pixiv_id" placeholder="邮箱地址/pixiv ID" autocapitalize="off" autocomplete="off">
</div>
<div class="input-field">
<input type="password" name="password" placeholder="密码" autocapitalize="off" autocomplete="off">
</div>
</div>
<ul class="error-msg-list"></ul>
<button type="submit" class="signup-form__submit">登录</button>
<div class="signup-form-nav">
<div class="left"></div>
<div class="right"><a href="https://www.pixiv.net/reminder.php" target="_blank">忘记了</a></div>
</div>
</form>
</div>
发现需要 post 如下参数:
参数名 | 说明 |
---|---|
post_key | 类似于 token |
return_to | 回跳地址 |
lang | 语言 |
source | 来源 |
pixiv_id | 用户名 |
password | 密码 |
提交的表单网址: https://accounts.pixiv.net/login
因为有 token 的存在,所以提交的时候也需要登录页的生成的 cookie,不提交 cookie 的后果就是如下的 400 Bad Request:(/´Д`)/
下面直接上全宇宙最好的语言进行登录(啪)
需要注意,首先需要安装一个 HTML DOM 解析包 sunra/php-simple-html-dom-parse
,运行一下 composer require "sunra/php-simple-html-dom-parser"
就行了。
主要的代码:
use Sunra\PhpSimple\HtmlDomParser;
define('BEFORE_LOGIN_COOKIE', __DIR__ . '/BEFORE_LOGIN_COOKIE.txt');//登录页面的cookie
define('AFTER_LOGIN_COOKIE', __DIR__ . '/AFTER_LOGIN_COOKIE.txt');//登录成功后获取到的cookie
define('USER_AGENT', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.59 Safari/537.36');
function login_pixiv($username, $password)
{
$login_url = 'https://accounts.pixiv.net/login';
//获取登陆页cookie
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $login_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_COOKIEJAR, BEFORE_LOGIN_COOKIE);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
curl_setopt($ch, CURLOPT_USERAGENT, USER_AGENT);
$login_html = curl_exec($ch);
curl_close($ch);
$dom = HtmlDomParser::str_get_html($login_html);
$form = $dom->find('#old-login', 0)->find('form', 0);
$data['post_key'] = $form->find('input[name="post_key"]', 0)->value;
$data['return_to'] = $form->find('input[name="return_to"]', 0)->value;
$data['lang'] = $form->find('input[name="lang"]', 0)->value;
$data['source'] = $form->find('input[name="source"]', 0)->value;
$data['pixiv_id'] = $username;
$data['password'] = $password;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $login_url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_COOKIEFILE, BEFORE_LOGIN_COOKIE);
curl_setopt($ch, CURLOPT_COOKIEJAR, AFTER_LOGIN_COOKIE);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
curl_exec($ch);
curl_close($ch);
}
调用 login_pixiv()
方法登录成功获取到 cookie 后,就可以为♂所♂欲♂为了,这个 cookie 的有效期为一个月,提供一个验证 cookie 是否有效的方法:
function is_cookie_ok($cookie)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://www.pixiv.net/setting_profile.php');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
curl_setopt($ch, CURLOPT_USERAGENT, USER_AGENT);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie);
$response = curl_exec($ch);
curl_close($ch);
$headers = [];
$header_text = substr($response, 0, strpos($response, "\r\n\r\n"));
foreach (explode("\r\n", $header_text) as $i => $line) {
if ($i === 0) {
$headers['http_code'] = $line;
} else {
list($key, $value) = explode(': ', $line);
$headers[$key] = $value;
}
}
if (strpos($headers['http_code'], '200') === false) {
return false;
}
return true;
}