如何分析Spark3大数据实时处理Streaming+Structured Streaming 的实战,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。
昨天下午准备随便找找高铁票时,突然对12306的登录产生了兴趣,于是研究了一下,先说明两点:
验证码
这部分调用的是一个大佬现成的API,如果各位大佬对识别验证码部分感兴趣,我这个小菜鸡很抱歉帮不上忙
登录表单
实际上12306登录的表单十分简单,字段少JS代码基本没什么难度,所以想看高阶JS逆向的姐姐可能要失望了
既然没什么难点,那有人可能就问了为什么还要水一篇文章?
原因就是12306登录过程中还是有不少坑,虽然单个页面请求字段少,但顶不住一个登录请求居然有十来个请求页面,在这个过程中各种自动手动设置Cookie,如果你憨憨的只请求登录url是永远失败的(别问我怎么知道的!),浪费我好几个小时时间。
浏览器开发者工具
Fiddler或Charles等抓包工具
建议使用抓包工具,因为请求太多时控制台不是很直观,控制台主要用于JS调试,虽然登录12306基本不需要用到调试
首先运行抓包工具监听,在浏览器打开12306的主页手动登录一次,登录成功后就可以抓包监听了,我这里用的是Charles
显示的结果有很多,但是不要怕,大部分都是静态文件,除掉静态文件其他相关请求大概也就十五六个...
我一开始被N次登录失败搞上头了总觉得12306在请求上埋坑于是还真按着这十多个请求一路写下去...
后来想想其实没必要这么做,关注主要的几个登录请求中的Cookie字段来源再针对性发出请求就好了,事后也证明只需要经过6个请求,就能成功登录。
所以本文我会着手从关键的几个登录请求分析,就不赘述摸索过程的痛了。
生成验证码的URL很容易找到
https://kyfw.12306.cn/passport/captcha/captcha-image64?login_site=E&module=login&rand=sjrand&1589797925252&callback=jQuery191020097810026343454_1589797924079&_=1589797924080
请求字段
响应image就是经过base64验证码图片,验证码图片从这里就可以拿到了
重点说Cookie,虽然字段有点多,但其实只要关注使用JS手动设置的字段就可以了,因为Session会帮我们处理响应头里的Cookie,重点就是确定哪些字段不是通过响应头设置的,可以直接搜索字段,比如第一个_passport_session
在一个JS文件中出现了该字段,这表明是手动添加的,需要重点关注,既然是手动添加的字段要么是JS计算生成要么是服务器响应,可以先找找字段值
首先分析响应有三个字段exp、cookieCode和dfp,经比对exp和dfp就是验证码请求Cookie中的RAIL_EXPIRATION和RAIL_DEVICEID
其次看看这个请求本身:
https://kyfw.12306.cn/otn/HttpZF/logdevice?algID=y6fvmhGlLP&hashCode=WRXET1wCtYsDWujgBBDiq2A4aqJOy-G6t5VK5OI0wNY&FMQw=0&q4f3=zh-CN&VPIf=1&custID=133&VEek=unknown&dzuS=0&yD16=0&EOQP=c227b88b01f5c513710d4b9f16a5ce52&jp76=52d67b2a5aa5e031084733d5006cc664&hAqN=MacIntel&platform=WEB&ks0Q=d22ca0b81584fbea62237b14bd04c866&TeRS=709x1280&tOHY=24xx800x1280&Fvje=i1l1o1s1&q5aJ=-8&wNLf=99115dfb07133750ba677d055874de87&0aew=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36&E3gR=92271eade53193a7130e280652b8e939×tamp=1589810100160
请求参数虽然有很多,但浏览器打开是可以直接响应结果的,所以暂且不管它,实际上这些参数的生成过程还是有点意思的,过两天我会专门写一篇分析这部分JS参数的文章,现在我们直接使用访问拿到的结果就能通过
回到获取验证码的请求cookie上来,经过分析发现除开RAIL_EXPIRATION和RAIL_DEVICEID其他字段都是响应头设置的,所以在获取验证码图片这一步我们只需要进行两个请求:
import reimport requests headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36','Referer': 'https://kyfw.12306.cn/otn/resources/login.html','Host': 'kyfw.12306.cn'} session = requests.Session()# p1这些字段其实基本就是获取设备信息再进行加密处理p1 = {'algID': 'y6fvmhGlLP','hashCode': 'WRXET1wCtYsDWujgBBDiq2A4aqJOy-G6t5VK5OI0wNY','FMQw': 0,'q4f3': 'zh-CN','VPIf': 1,'custID': 133,'VEek': 'unknown','dzuS': 0,'yD16': 0,'EOQP': 'c227b88b01f5c513710d4b9f16a5ce52','jp76': '52d67b2a5aa5e031084733d5006cc664','hAqN': 'MacIntel','platform': 'WEB','ks0Q': 'd22ca0b81584fbea62237b14bd04c866','TeRS': '709x1280','tOHY': '24xx800x1280','Fvje': 'i1l1o1s1','q5aJ': '-8','wNLf': '99115dfb07133750ba677d055874de87','0aew': headers['User-Agent'],'E3gR': '92271eade53193a7130e280652b8e939','timestamp': int(time.time() * 1000) }# 第一次请求获取exp和dfpr1 = session.get('https://kyfw.12306.cn/otn/HttpZF/logdevice', params=p1, headers=headers) exp = re.search(r'exp":"(\d+)",', r1.text).group(1) dfp = re.search(r'dfp":"(.+?)"', r1.text).group(1) cookieCode = re.search(r'cookieCode":"(.+?)"', r1.text).group(1) # 这个字段暂时不确定作用session.cookies.update({'RAIL_DEVICEID': dfp, 'RAIL_EXPIRATION': exp}) # 手动添加cookie# 第二次请求获取验证码p2 = {'login_site': 'E','module': 'login','rand': 'sjrand',str(int(time.time() * 1000)): ''} r2 = session.get('https://kyfw.12306.cn/passport/captcha/captcha-image64', params=p2) image = re.search(r'image":"(.+?)",', r2.text).group(1)
验证码图片就成功拿到了
先随便在验证码图片上点一下,然后右键检查元素
发现当在图片上标记一个点,页面就会生成一个div标签,很简单就能推测出randcode就是提交答案,它的数值就是图片所在的平面位置点,我们可以随意的在8个图中取一个点作为第几张图的映射,如
position = {1: '49,48', 2: '124,52', 3: '200,43', 4: '259,47',5: '50,113', 6: '101,102', 7: '198,112', 8: '250,127'}def getVerifyResult(path: str):"""调用API接口获取验证码结果 :param path: 验证码图片路径 :return: """url = "http://littlebigluo.qicp.net:47720/"ret = []# 发送post请求把图片数据带上file = open(path, 'rb') response = requests.post(url, data={"type": "1",}, files={'pic_xxfile': file}) file.close()# 返回识别结果for i in re.findall("<B>(.*)</B>", response.text)[0].split(" "): ret.append(position[int(i)])return ret
接下来调用上面的识别函数获取答案
import base64 code_path = "code.jpg"imgdata = base64.b64decode(image)with open(code_path, 'wb') as f: f.write(imgdata) capchat = getVerifyResult(code_path) answer = ','.join(capchat)
Cookie和响应,都是老东西中规中矩没有需要注意的
看完上述内容,你们掌握如何分析Spark3大数据实时处理Streaming+Structured Streaming 的实战的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注亿速云行业资讯频道,感谢各位的阅读!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。