click.js
2.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
'use strict';
var cutil = require('./util');
module.exports = function (encoding, client, cheerio) {
/**
* a要素のリンク/submit系ボタンのクリックをエミュレート
*
* a要素: リンク先のページを取得
* submit系ボタン: 所属フォームのsubmit
*
* @param callback リクエスト完了時のコールバック関数(err, response, body(buffer))
*/
var emulateClick = function (elem, callback) {
var doc = cutil.documentInfo(elem);
var $link = null;
// a要素でなければエラー
try {
if (elem.length === 0) {
throw new Error('no elements');
}
// 複数ある場合は先頭の要素のみ
$link = elem.eq(0);
// submit系要素の場合はsubmit()に飛ばす
var type = $link.attr('type');
var is = {
a: $link.is('a'),
input: $link.is('input'),
button: $link.is('button')
};
if ((is.input || is.button) && cutil.inArray([ 'submit', 'image' ], type)) {
var $form = $link.closest('form');
var param = {};
var name = cutil.paramFilter($link.attr('name'));
if (name.length > 0) {
if (type === 'submit') {
// submit: 押したボタンのnameとvalueを送信する
param[name] = $link.val() || $link.attr('value');
} else {
// image: 押したボタンのname.xとname.y座標を送信する(ダミーなので0)
param[name + '.x'] = 0;
param[name + '.y'] = 0;
}
}
return $form.submit(param, callback);
}
// submit系要素でもa要素でもなければエラー
if (! is.a) {
throw new Error('element is not clickable');
}
} catch (e) {
return client.error(e.message, {
param: { uri: doc.url },
callback: callback
});
}
return client.run('GET', $link.url(), {}, null, callback);
};
/**
* 非同期クリック
*/
cheerio.prototype.click = function (callback) {
return emulateClick(this, callback);
};
/**
* 同期クリック
*/
cheerio.prototype.clickSync = function (callback) {
return emulateClick(this, 'sync');
};
};