superagent post php,node模拟登录segmentfault

前言

前段时间看的爬虫都是不需要登录直接爬取数据,这回就试试爬取需要登录的网站信息吧,说干就干,直接就拿segmentfault做为目标!

一、爬虫所需模块

superagent

async

二、分析

我们首先用chrome或者其他浏览器打开segmentfault的主页,找到它的登录接口,点击登录接口,记得把Preserve log勾上,否则跳转之后找不到接口,如图(重要信息打了马赛克):

bVbdwop?w=986&h=664

显而易见这是一个post请求,三个参数分别是用户名、密码、和是否记住密码的标记。

获取Cookie里的PHPSESSID

仔细看请求头header里的cookie,在请求发送的时候就已经有了,我们直接把整个请求头拿过来,就直接用图中的接口和header登录,逐一删除cookie中的项,测试登录结果,最终发现只有PHPSESSID是必须的。这个PHPSESSID如何获取呢?我们可以在登录之前先访问segmentfault主页,将返回的cookie拿到,再在登录的时候加上这个cookie即可。

获取cookie的代码如下:

(cb) => {

superagent

.get('https://segmentfault.com')

.end((err, res) => {

if (err) console.log(err)

cookie = res.headers['set-cookie'].join(',').split(';')[0] // 获取PHPSESSID

cb(null)

})

}

获取Query String Paramsters里的 _ 参数

还有一个参数需要注意:接口中的Query String Paramsters的_参数,那么这个参数是怎么来的呢?在返回的response的header里寻找并没有找到它的踪迹,所以猜想它应该是隐藏在源码里,我们直接在chrome控制台的source下全局搜索_=(source顶部右键选择search in all files即可出现全局搜索框),逐一排查可能性:

bVbdwc1?w=1342&h=569

bVbdwgX?w=829&h=589

排查过程中发现箭头所指的ajaxSend函数好像和我们需要的有关系:它紧邻的下面的delegate函数内容应该就是登陆有关的内容,通过/api/user/?do=login和submit等就可以清楚的看出,这个函数中的url是从n.attr('action')拿到的,猜测这个n.__肯定和请求中的Query String参数脱不了关系。正好这个ajaxSend函数中就有n.__,也正好验证了我们刚才的推测,分析这行代码:

n.url.indexOf("?") === -1 ? n.url = n.url + "?_=" + i._ : n.url = n.url + "&_=" + i._

n.url默认是n.url + "?_=" + i._ ,那么这个i.__应该就是最终boss,就在这个文件中找到定义i的代码,如上图箭头所指,继续全局搜索SF.token,最终在index.html中找了生成它的代码,包含在一个script中,如图:

bVbdwia?w=836&h=631

找到来源就简单了,我们仍然是在登录直接先访问主页,将整个主页的html代码拿到,然后将这个script的内容取出来不就行了,哈哈,好开心~

获取script的代码如下:

var cheerio = require('cheerio')

function getRandom(s) {

let $ = cheerio.load(s)

let script = $('script').eq(8).html()

let fn = new Function('window', script + ';return window.SF.token')

let token = fn({})

$ = null

return token

}

exports.getRandom = getRandom

到这里,登录就算完成了一大半了,接下来就是简单的用superagent调用接口啦,这里的请求头出了cookie的其他部分也是必须要设置的,可以直接从浏览器上copy下来,代码如下:

(cb) => {

const username = process.argv[2]

const password = process.argv[3]

console.log(cookie)

console.log(random)

let header = {

'accept': '*/*',

'accept-encoding': 'gzip, deflate, br',

'accept-language': 'zh-CN,zh;q=0.9',

'content-length': '47',

'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',

'cookie': `PHPSESSID=${cookie};`,

'origin': 'https://segmentfault.com',

'referer': 'https://segmentfault.com/',

'user-agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36',

'x-requested-with': 'XMLHttpRequest'

}

superagent

.post(`https://segmentfault.com/api/user/login`)

.query({'_': random})

.set(header)

.type('form')

.send({

username: username,

password: password,

remember: 1

})

.end(function(err, res) {

if (err) {

console.log(err.status);

} else {

console.log('返回状态码: ' + res.status)

cb(null)

}

})

},

终于返回200了,美滋滋,然后我们继续~比如我我想用代码修改个人主页的个人描述内容,首先我们先找到相关接口,如图:

bVbdxXp?w=1071&h=828

这个post请求的参数description就是个人描述的所填写的新的内容,我们直接用superagent调用这个接口

(cb) => {

superagent

// 编辑右上角个人说明

.post('https://segmentfault.com/api/user/homepage/description/edit')

.query({'_': random})

.set(header)

.type('form')

.send({

description: '努力coding的小喵~~~'

})

.end((err, res) => {

if(err) throw err

let result = JSON.parse(res.text)

if (result.status === 0) {

console.log('编辑成功')

} else {

console.log('编辑失败:' + result.data)

}

})

cb(null, 1)

}

返回状态码200,然后直接去浏览上的主页刷新下,可以看到个人描述的内容已经成功更新了!

bVbdyF8?w=445&h=212

总结

打开segmentfault主页并登陆,找到登录请求的接口并分析

用node登录之前,先请求主页接口,目的是拿到PHPSESSID和源代码中的生成Query String的函数

带着这两个参数去请求登录接口,记得设置请求头

登录成功之后就可以干任何你想干的事情啦

整个登录过程耗费了很久的时间,有空就研究这个Query String的来源,好不容易登录成功想干点事情,又没注意到设置请求头,以为是sf_remember参数的问题,又折腾了许久,还好,最终总算是成功了!感谢自己的不放弃~

源码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值