让我大吃一堑的前后分离 web 站模拟登录
很多 Web 站都采用前后端分离的技术。以前保存用户身份信息靠 Cookie,那前后分离这种技术组合靠什么校验用户身份呢?看起来正常的数据,发送过去为什么总是 400 呢?
一、背景
scrapy 模拟登录相信大家都会,而且非常的熟练。但是技术一直在进步(尤其是前端领域),近几年前后端分离的趋势越来越明显,很多 web 站都采用前后端分离的技术。以前保存用户身份信息靠 Cookie,那前后分离这种技术组合靠什么校验用户身份呢?
二、登录操作
前后端分离的项目,一般都是 react、vue 等 js 库编写的,进而涌现出了一批优秀的前端框架或组件,如阿里巴巴前端团队的 AntDesign,饿了么前端团队的 ElementUI 等。由于前后端分离的原因,后端必定有 API,所以最好的爬取策略不是在页面使用 CSS 定位或者 Xpath 定位,而是观察网络请求记录,找到 api 以及请求时发送的参数并用 Python 进行构造、模拟请求。
以这里的登录为例,通过css定位其实也可以,但是有不稳定的风险。所以还是看api和参数比较稳妥,前端变化的几率比后端高出太多。在页面中打开调试工具,然后定位到『网络』选项卡,接着打开登录页并输入用户名密码并登录。
在请求记录中找到并选中方法为 post 的那条记录就可以查看此请求的详细信息,比如请求地址、请求头和参数。请求详情如下图所示:
请求参数如下图所示:
在这里输入图片标题
可以看到请求参数中有用户名、密码以及用户名类型(比如手机号或邮箱)。得到完整的请求信息后就可以根据请求地址、请求头和参数来构造登录用的代码,Scrapy 常用登录代码如下:
def start_requests(self): """ 重载start_requests方法 通过is_login方法判断是否成功登录 """ login_url = "http://xxx.yyy.ccc.aa/api/v1/oauth/login" login_data = { "username": "abcd@easub.com", "password": "faabbccddeeffggd5", "type": "email" } return [scrapy.FormRequest(url=login_url, formdata=login_data, callback=self.is_login)] def is_login(self, response): """ 根据返回值中的message值来判断是否登录成功 如果登录成功则对数据传输页发起请求,并将结果回传给parse方法 如果登录失败则提示 由于后面的用户权限验证需要用到token信息,所以这里取到登录后返回的token并传递给下一个方法 """ results = json.loads(response.text) if results['message'] == "succeed": urls = 'http://xxx.yyy.ccc.aa' access_token = results['data']['access_token'] print("登录成功,开始调用方法") yield Request(url=urls, callback=self.parse, meta={"access_token": access_token}) else: print("登录失败,请重新检查") 复制代码
如果返回信息的 json 里面 message 值为 succeed 即认为登录成功并调用 parse 方法
作者:云享专家韦世东
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
- 点赞
- 收藏
- 关注作者
评论(0)