当前位置: 首页 > news >正文

爬虫模拟登陆 SegmentFault

前言

本文来自我在 SegmentFault 上的 回答,我纪录了其中精彩的部分到本博客。

大致意思是模拟登陆 segmentfault.com,一时手痒,本文将带领大家一起实现这个操作。

解析

这个问题问的非常好,但可惜的是大家的回复都是纸上谈兵未经探讨,最前最高票的回答的竟然说让下抓包工具,简直可笑啊,chrome下F12直接就可以看到账号密码是明文发送的何必还要抓包?另外的题主的http头就是从chrome下复制的。

根据竟然我判断你的问题的原因是发送了过多的http头,其中Content-Length是明显有问题的,这个代表内容长度,你这次抓包是49,但下次换个账号密码可就真不一定了。比如,如果账号密码过长,可能就会导致截断,那么无论如何都会提示密码错误的(因为只发送了一部分的密码过去)。

方案

事实上为了探究这个有意思的问题,我专门动手做一个有意思的实验。这里就用个最简单的脚本语言node.js中的ajax模型来重新构建操作过程。

分析

我们先去登陆页--源码页去大致看一下,其中

<script crossorigin src="https://dfnjy7g2qaazm.cloudfront.net/v-575e20ec/user/script/login.min.js"></script>

这个跨域请求加载js脚本,看名字应该是和登陆有关的,我们这边使用尝试访问下,结果不用想,一篇乱糟糟的。

根据命名规范,我们猜测压缩前的名字可能就是叫login.js,我们看下他删除了没有,我们尝试访问https://dfnjy7g2qaazm.cloudfront.net/v-575e20ec/user/script/login.js,嗯哼还在,看来他们的发布人员可能不是处女座的。

那好我们往下看下这里:

$("form[action='/api/user/login']").submit(function() {
  var data, url;
  url = '/api/user/login';
  data = $(this).serialize();
  $.post(url, data, function(d) {
    if (!d.status) {
      return location.href = d.data;
    }
  });
  return false;
});

代码非常简单,我们知道了请求结果中status为0时代表登陆成功,同时我们也知道了后台执行登陆请求页是/api/user/login,即https://segmentfault.com/api/user/login,我们访问一下,嗯404。这说明了服务端验证了输入,并判断我们的请求不符合正常逻辑。下面我们开始伪造请求头。

请求头

我们用类似chrome的现代化浏览器,正常访问https://segmentfault.com/user/login,按下F12,选择network面板开始监控请求,然后我们随意填写账号密码,点击登陆。

这个时候下面会有一条信息,我们提取其中的Request Header如下

POST /api/user/login?_=93e1b923149fb56c4fd329fe95ea4001 HTTP/1.1
Host: segmentfault.com
Connection: keep-alive
Content-Length: 46
Pragma: no-cache
Cache-Control: no-cache
Accept: */*
Origin: https://segmentfault.com
X-Requested-With: XMLHttpRequest
User-Agent: xxxx
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
DNT: 1
Referer: https://segmentfault.com/
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.8,zh-CN;q=0.6,zh;q=0.4
Cookie: PHPSESSID=web5~to8l5ovmt9t3jkb84aevuqf151; Hm_lvt_e23800c454aa573c0ccb16b52665ac26=1465799317; Hm_lpvt_e23800c454aa573c0ccb16b52665ac26=1465799317; _ga=GA1.2.915515414.1465799317; _gat=1

我们只需要同样发送这些请求到服务器上,理论上就不会有问题,同时也不会再404了。

这里面的数据中,有些不需要发的,有些是必须要发送的。我们可以一一测试下。

调试

我们这里使用nodejs来简单写段代码测试下服务端所验证的参数。

枯燥的测试就是不断删减请求来看看服务端会不会返回404。过程不再赘述,结果是:

  1. querystring中的 _必须和Cookie中的PHPSESSID对应。

  2. X-Requested-With的值需要带ajax请求标志,即XMLHttpRequest

  3. Referer的值

看来他们服务端还是蛮严格的。

源码

var superagent = require('superagent');


superagent.post('https://segmentfault.com/api/user/login?_=7ef046ad4f224034d7b51655238bd870')
    .set('Referer', 'https://segmentfault.com/user/login')
    .set('X-Requested-With', 'XMLHttpRequest')
    .set('Cookie', 'PHPSESSID=web1~395mahoqliohh5kclv894ibpr3; _gat=1; _ga=GA1.2.1234754628.1465797373; Hm_lvt_e23800c454aa573c0ccb16b52665ac26=1465797373; Hm_lpvt_e23800c454aa573c0ccb16b52665ac26=1465797538')
    .send({
        mail: "xxxxxx",
        password: "xxxx"
    })
    .type('form')
    .end(function(err, res) {
        if (err || !res.ok) {
            console.log(err.status);
        } else {
            console.log('yay got ' + JSON.stringify(res.body));
        }
    });

同时,开源在 GitHub 上,地址 segmentfault_loginer:https://github.com/Rozbo/segmentfault_loginer。

相关文章:

  • 《OOD启思录》:61条面向对象设计的经验原则
  • 学习C语言指针和链表的体会
  • [bzoj1912]异象石(set)
  • nginx源码分析——配置
  • 模糊查询和聚合函数
  • maxsdk sample中3dsexp.rc点不开并提示specstrings.h中找不到sal.h解法
  • 移动端开发调试工具神器--Weinre使用方法
  • Python:判断一个字典里面key是否存在
  • 精仿今日头条
  • Oracle GoldenGate 快速安装配置实用指南
  • JavaScript 开发人员需要知道的简写技巧
  • Deep Learning(深度学习)学习笔记整理系列之(二)
  • 个人喜欢的php开源类库
  • JAVA之旅(十七)——StringBuffer的概述,存储,删除,获取,修改,反转,将缓存区的数据存储到数组中,StringBuilder...
  • 智能资产配置特训班课程过半,这些内容关键点你不能错过
  • $translatePartialLoader加载失败及解决方式
  • 《Javascript高级程序设计 (第三版)》第五章 引用类型
  • CSS 三角实现
  • dva中组件的懒加载
  • ES6简单总结(搭配简单的讲解和小案例)
  • IDEA常用插件整理
  • JavaScript-Array类型
  • JavaScript异步流程控制的前世今生
  • Java的Interrupt与线程中断
  • PaddlePaddle-GitHub的正确打开姿势
  • SegmentFault 2015 Top Rank
  • tweak 支持第三方库
  • vue:响应原理
  • 阿里云爬虫风险管理产品商业化,为云端流量保驾护航
  • 从伪并行的 Python 多线程说起
  • 基于webpack 的 vue 多页架构
  • 深入 Nginx 之配置篇
  • 推荐一款sublime text 3 支持JSX和es201x 代码格式化的插件
  • 小程序测试方案初探
  • - 语言经验 - 《c++的高性能内存管理库tcmalloc和jemalloc》
  • 运行时添加log4j2的appender
  • 正则与JS中的正则
  • HanLP分词命名实体提取详解
  • Unity3D - 异步加载游戏场景与异步加载游戏资源进度条 ...
  • #HarmonyOS:基础语法
  • #NOIP 2014# day.1 生活大爆炸版 石头剪刀布
  • $分析了六十多年间100万字的政府工作报告,我看到了这样的变迁
  • (17)Hive ——MR任务的map与reduce个数由什么决定?
  • (2009.11版)《网络管理员考试 考前冲刺预测卷及考点解析》复习重点
  • (env: Windows,mp,1.06.2308310; lib: 3.2.4) uniapp微信小程序
  • (NO.00004)iOS实现打砖块游戏(九):游戏中小球与反弹棒的碰撞
  • (二)PySpark3:SparkSQL编程
  • (附源码)springboot助农电商系统 毕业设计 081919
  • (六)c52学习之旅-独立按键
  • (三维重建学习)已有位姿放入colmap和3D Gaussian Splatting训练
  • (一)认识微服务
  • (转)Linux NTP配置详解 (Network Time Protocol)
  • (转)全文检索技术学习(三)——Lucene支持中文分词
  • ****Linux下Mysql的安装和配置
  • .bat批处理(十一):替换字符串中包含百分号%的子串