最近的项目在做一些数据方面的集成,五花八门的系统对应的接口更是千奇百怪,数据集成的过程总结成八个字就是:逢山开路,遇水架桥。
恰好这两天碰到一个问题,我们要集成的WEB系统没有提供专门的数据集成接口,没有API可以调,数据库更是不让访问,万般无奈之下,我在想是否可以用python自动爬取页面。web页面有SSO,用的应该是开源的CAS框架,并且后面的页面全都是由动态JS、AJAX异步加载进去的,这显然不像普通的静态页面那样直接用Scrapy上去就是一顿干,要完美的模拟登陆动作并且还要爬取后面的动态内容,对页面结构和爬取内容的分析是必不可少的。
工具Chrome
页面分析工具非常简单,只需要最新版本的Chrome浏览器即可python3
requests
打开登录页面,按F12打开Chrome自带的分析工具,在Network选卡上可以看到当前浏览器显示页面和提交登录信息的详情,如下图
某网站登录页面
从截图上可以看到,当我们访问app/这个url的日志,因为我们还没有登录过,SSO会把我们自动重定向到登录页面,所以http status是302重定向。
接下来我们在页面上输入账号密码,点登录按钮,通过页面追踪分析并模拟整个登录过程,这个过程要尤其仔细,因为很多CAS在登录页面上埋了很多隐藏的标记,一个地方模仿的不对可能就会登录失败然后又被重定向到开始的地方。
分析登录过程
从分析可以看到,登录按钮提交的时候会用POST方式提交一个表格,而表格里面的除了账号密码等显眼的字段以外还有一个lt,经验告诉我们这个字段应该隐藏在之前的登录页面上,用来校验登录页面的合法性,所以我们要从登录页面上找到并提取这个信息。同时还要注意http的消息头,最好按照浏览器抓取的消息头去构造,因为网站同样会校验这里面的信息。
下面是登录的主要代码,我们基于python3和requests包来处理https访问请求,模拟浏览器的行为将认证需要的信息构造出来发给网站。
import requestsimport urllib3from lxml import etreefrom ows_scrapy.ows_spider.write_csv import write_list_to_csv
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
s = requests.session()
s.trust_env = False # fastercookie = Noneusername = 'username'password = 'pwd'def login():
header = { 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,**; q=0.01', 'Accept-Encoding': 'gzip, deflate, br', 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8', 'Connection': 'keep-alive', 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8', 'Host': '.com', 'Origin': 'https://.com', 'Referer': 'https://.com/app/104h/spl/test/ID_480_1511441539904_workflowdetail.spl?orderid=SOC-20180220-00000003', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36', 'X-Requested-With': 'XMLHttpRequest'
}
print('Start to scan order id ' + order_id)
url = 'https://.com/app/pageservices/service.do?forAccessLog={serviceName:test_gscsocsecurityincidentmanage_log_getList2,userId:571bdd42-10ca-4ce1-b41c-8a3f6632141f,tenantId:104h}&trackId=fec68f8e-f30a-4fa1-a8b1-41d3dd11fa4c'
res = s.post(url, headers=header, params=form_data, cookies=cookie, allow_redirects=False, verify=False) #要加载上面登录成功的cookie
print(res.content) return res 要点其实就是从XHR里找到请求的URI,构造请求报文头和提交表格,最后务必要加上登录成功的cookie,否则会被重定向到登录页面。
抓取动态页面的方法还有很多,这种方法依赖的包相对较少,代码比较灵活,在爬取复杂的登录页面的时候效果比较好,只是在分析页面登录机制的时候要尤其细心。
作者:半夜菊花茶
链接:https://www.jianshu.com/p/8cd6e9bc2680



