做模拟登录,登录名是中文,然后 POST 的地址是 GBK 编码的,但是登录不成功,应该是中文参数的编码问题,看到一个用 request
模块的相似问题,https://cnodejs.org/topic/56d2e1c69f876b7e665857c9,最后用它的 write 方法解决,superAgent 貌似也有 write 方法, https://github.com/visionmedia/superagent/blob/v1.7.2/lib/node/index.js#L483,试了几次没能成功,求老司机指导下,谢谢!
试了下 request 确实是可以的,想知道用 superAgent 能不能搞?
能啊…
@magicdawn 求指导啊哥 …
@alsotang 唐大哥,貌似不是这个问题,传输的数据是已经编码了过的,具体情况和 https://cnodejs.org/topic/56d2e1c69f876b7e665857c9 一样,把参数写在 request 的 write() 里就没问题了
@hanzichi 把传输的数据用 gbk 编码,给你推荐的库就是做编码用的,可以指定 charset。
@magicdawn 这个 write 的方式,太难看了,我给差评
superagent.post('url')
.send({
loginname: urlencode2('中文名', 'gbk')
})
@alsotang 我是抓了实际 POST 的包,然后直接把编码后的参数填上去的,如果直接写在 superAgent 的 send,一直报用户名出错,如果用 https://cnodejs.org/topic/56d2e1c69f876b7e665857c9 那样写,却是可以的,可能是因为那个帖子里说的 “用一段代码手工把中文转换成gb2312编码的字符串,但把转换过的字符串传到request的form中去后,request又会对其中的%编码为%25,所以也不行”
哈哈 @alsotang 没办法, 写在正常的参数里会被再 urlencode 一次
superagent 有啥问题…贴代码啊…
superagent.Request.prototype.send 还和 req content-type 有关系
@magicdawn 就是同样的问题,我试了下用 request 的 write 方法是可以的,能不能用 superAgent 解决?就像您说的 “写在正常的参数里会被再 urlencode 一次”,superAgent 正常的写法不行 。。用了下 superAgent 的 write,可能是姿势不对,文档也没找到 write 方法,求大神赐教 。。
const request = require('superagent')
const urlencode = require('urlencode')
request.post(url)
.write(urlencode('para=中文参数', 'gbk'))
.end((err, res) => {
// ...
});
这样呢
superAgent 正常的写法不行 。。
正常写法?
用了下 superAgent 的 write,可能是姿势不对,文档也没找到 write 方法
贴代码啊
superagent.post('url')
.send(
urlencode2.stringify({loginname: '中文名'}, 'gbk') // this is a string
)
request{
url: url,
method: 'POST',
body: urlencode2.stringify({loginname: '中文名'}, 'gbk') // this is a string
}
百分号的问题,我大意了。不过 superagent 和 request 好像都有发送 raw body 的方式
中文参数已经编码过了。
这样是 ok 的。
var request = require('request');
var iconv = require('iconv-lite');
var post_request =
request
.post({
url: 'https://xx.com',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Cookie': 'PHPSESSID=xx'
},
encoding: null // 关键代码
}, function (err, sres, body) {
// gbk 页面乱码
var html = iconv.decode(body, 'gb2312');
console.log(html);
});
// form data
post_request.write("a=xx&b=xx&c=xx");
这样报错(TypeError: superagent.post(…).set(…).set(…).write(…).end is not a functi on):
var superagent = require('superagent');
superagent
.post('https://xx.com')
.set("Content-Type", "application/x-www-form-urlencoded")
.set("Cookie", "PHPSESSID=xxx")
.write("a=xx&b=xx&c=xx") // form data
.end(function(err, sres) {
fs.writeFileSync("test.txt", sres.text);
});
求赐教大神
sorry superagent.Request.prototype.write 返回不是 this https://github.com/visionmedia/superagent/blob/v2.3.0/lib/node/index.js#L320-L332
var superagent = require('superagent');
var req = superagent
.post('https://xx.com')
.set("Content-Type", "application/x-www-form-urlencoded")
.set("Cookie", "PHPSESSID=xxx")
req.write("a=xx&b=xx&c=xx") // form data
req.end(function(err, sres) {
fs.writeFileSync("test.txt", sres.text);
});
@alsotang
send 需要注意 content-type 和 send参数, 不同组合有不同的序列化策略 https://github.com/visionmedia/superagent/blob/v2.3.0/lib/request-base.js#L348-L365
不过 req.send(string)
+ application/x-www-form-urlencoded
也就啥都没干, 和 write 一样吧
不过既然 send 要去读代码, 要是我, 就直接 req._data = xxx
了 😂
嗯, superagent 里的 urlencode 操作发生在 qs.stringify, 以前总是纠结要不要手动 encodeURIComponent 😂
@alsotang superAgent 报错了," Cannot read property ‘charset’ of undefined" …
代码大概这样
var superagent = require('superagent');
var urlencode2 = require("urlencode2");
superagent
.post('https://xx.com')
.set("Content-Type", "application/x-www-form-urlencoded")
.set("Cookie", "PHPSESSID=xxx")
.send(urlencode2.stringify({username: 'xx'}, 'gbk'))
.send({'checkCode': '8876'})
.end(function(err, sres) {
console.log(sres.text);
});
@magicdawn 厉害阿!这样可以了!谢谢大大
原来你就是 superagent-charset 的作者阿,superagent-charset 很好用!
@magicdawn @alsotang 借宝地再请教两位大大一个问题,想做验证码自动识别,用的是这个库 https://github.com/naptha/tesseract.js,验证码是 PHP 生成的,如果我手动在浏览器中复制验证码这个图片,然后粘贴到本地,是可以识别的,如果用 Node 下载下来,就报错,图片看起来一模一样阿,直接打开这个验证码地址是乱码,图片下载用的代码如下,重命名为 png 格式的(粘贴下来的也是 png 格式的)。
// to download picture
function download(url, savePath) {
var req = http.get(url, function(res){
var binImage = '';
res.setEncoding('binary');
res.on('data', function(chunk){
binImage += chunk;
});
res.on('end', function(){
if (!binImage) {
console.log('image data is null');
return null;
}
fs.writeFile(savePath, binImage, 'binary', function(err){
if (err) throw err;
console.log('It\'s saved!'); // 文件被保存
});
});
});
}
是不是哪里姿势有误?
其实中文问题各种乱码应该感谢 iconv / iconv-lite 哈利路亚…
@hanzichi 八成是 buffer 在 ondata 的相加问题。
用 https://npm.taobao.org/package/superagentparse
看 .parse(parse('buffer'))
的例子来抓取图片吧。
@alsotang 看不懂… 囧