Py 获取 Flash Player amf 数据
网站:aHR0cDovL2pnc2IuYWdyaS5jbi9jb250cm9sbGVyP1NFUlZJQ0VfSUQ9UkVHSVNUUllfSkNTSl9NUkhRX1NIT1dfU0VSVklDRSZyZWNvcmRwZXJwYWdlPTE1Jm5ld3NlYXJjaD10cnVlJmxvZ2luX3Jlc3VsdF9zaWduPW5vbG9naW4=
安装 player后
开始正常操作:
1.打开network查看请求记录
发现多次会出现 amf 的包,查看包Response的内容发现里面的东西并不是需要的,但是来回就这几个包
2.使用FD(fiddler)抓包查看
发现里面还是有需要的数据的,使用requests库进行请求后,发现内容是空的
问题如下:
1.发包前,未按照该网站post请求正确组包
2.未正确发包并将返回数据进行解析查看
面对amf的数据包怎么办?
py提供了一个第三方库叫做 pyamf,pip安装即可
通过FD抓包,可以看到混淆的数据包,并不是特别方便,接下来使用小咖啡(charles)
小咖啡的界面比较清爽,经常用FD的可以试着用用小咖啡
点击AMF,在下方的content // body 有三个文件夹,里面就是需要的数据
【0】:代表分类的简称代码
【1】:代表省市的简称代码
【2】:各省市下的分类物品数据
Response的内容暂时分析到此,接下来分析Requests的内容
Content中的键值对就是需要伪造的关键参数(可以理解为form表单提交的参数)
注意区分当中不同的数据类型,比如对象、列表、字符串、空值
headers不同于正常模拟请求的headers,这里可以理解为amf数据的请求头
同样它也是一个对象,一个变量有键值对,可以设置属性,这样的行为在js中非常常见
那么py中呢,暂且不表
首先构造Requests需要的参数:
msg = messaging.RemotingMessage(messageId=str(uuid.uuid1()).upper(), clientId=str(uuid.uuid1()).upper(), operation='getHqSearchData', destination='reportStatService', timeToLive=0, timestamp=0)
(uuid可以单独了解下,py的一个库)
body的包怎么伪造呢,经过翻页的抓包发现它是一个对象
先新建一个类,类中的init方法携带body中需要的参数,通过pyamf.register_class()函数注册自定义的body参数类型
# 伪代码
registerClassAlias("personTypeAlias", Person);
pyamf.register_class(HqPara, alias='com.itown.kas.pfsc.report.po.HqPara')
这样'com.itown.kas.pfsc.report.po.HqPara'就会在请求的时候一并将对应的参数绑定在请求上发送至服务器,从而不会造成请求参数错误的情况
注册完body参数后,注册headers参数,并将数据包进行编码(或者理解为打包操作)
msg.body = [HqPara(), str(page_num), str(total_num)] print(str(page_num)) print(str(total_num)) msg.headers['DSEndpoint'] = None msg.headers['DSId'] = str(uuid.uuid1()).upper() # 按AMF协议编码数据 req = remoting.Request('null', body=(msg,)) env = remoting.Envelope(amfVersion=pyamf.AMF3) env.bodies = [('/1', req)] data = bytes(remoting.encode(env).read()) return data
# 指定请求的头部为 application/x-amf格式
# 返回的数据格式为 content 格式
req = requests.post(url, data, headers={'Content-Type': 'application/x-amf'}) return req.content
# 再进行解码,解析数据
amf_parse_info = remoting.decode(response) total_num = amf_parse_info.bodies[0][1].body.body[3] info = amf_parse_info.bodies[0][1].body.body[0] return total_num, info
数据已经拿到
// .*~~~~~~~~~~~~~~~~~~~
通过修改body中的参数及对象的定义,还可以拿到物品分类和地区代码的数据
不过随着player的支持越来越少,这样的网站反爬形式也越来越少见。
本文来自博客园,作者:黑山老道,转载请注明原文链接:https://www.cnblogs.com/meipu/p/14779235.html