Python调用Java代码抓取APP数据

需要用到的包:

  • jpype 
  • pymongo​ 
  • uuid0​ 

下载Fiddler,并配置好手机代理。

打开APP我们向下滑可以看到它在发送请求,通过Fiddler可以看到已经抓到请求了


image

image

多请求几次可以发现,只要知道signature怎么来的,我们就能模仿它的头部信息了。


image

这时候打开jadx,导入我们上次脱壳出来的源dex文件,按Ctrl+Shift+F输入signature进行搜索,找到这可以发现其他的头部信息在这,点进去看下


image

可以发现这就是我们要的,

image

image

点击生成signature的方法跳到它的声明,可以发现它是由时间戳拼接设备号进行md5加密的


image

 

image

 

我们可以直接使用这个方法,把它打包成jar进行调用。

import java.security.MessageDigest;

/* renamed from: com.hualong.framework.b.a */
public class MySig {
    /* renamed from: a */
    public static String m11218a(String str) {
        if (str == null) {
            return null;
        }
        StringBuffer stringBuffer = new StringBuffer();
        try {
            MessageDigest instance = MessageDigest.getInstance("MD5");
            instance.update(str.getBytes());
            for (byte b : instance.digest()) {
                stringBuffer.append(Integer.toString((b >>> 4) & 15, 16)).append(Integer.toString(b & 15, 16));
            }
        } catch (Exception e) {
        }
        return stringBuffer.toString();
    }
}

把java代码保存为 xxx.java文件,编译成class文件 , 然后编译成jar文件

javac MySig.java && jar cvf MySig.jar MySig.class

image.png

接下来编写Pythn代码

import time
from jpype import *
import jpype

uuid = 'IMEI867686020207104-IMSI460NNNNNNNNNNNN'
ti = str(int(time.time()))

ori_sig = uuid + "&&" + ti + "&&" + "f1190aca-d08e-4041-8666-29931cd89dde"

# 实例化一个Java虚拟机
jvmpath = getDefaultJVMPath()
# jar路径,不能有中文
jarpath = "D:/MySig/MySig.jar"
# 启动虚拟机
startJVM(jvmpath, "-ea", "-Djava.class.path=%s" % jarpath)
#print("aa", "-Djava.class.path=%s" % jarpath)
# 将类实例化对象
JDClass = JClass("MySig")
jd = JDClass()
# 调用m11218a方法
encry_sig = jd.get_sig(ori_sig)
java.lang.System.out.println(encry_sig)
#print(encry_sig)
# 关闭虚拟机,必须放在代码最后
shutdownJVM()

执行Python看下结果

image.png

接下来仿造请求头进行抓取

import requests
import time
from jpype import *
import jpype
import pymongo
import uuid0

# mongodb
MONGO_URI = 'localhost'
MONGO_DB = 'YinLiBo'
client = pymongo.MongoClient(MONGO_URI)
db = client[MONGO_DB]

def get_page(page):
    """翻页接口"""
    uuid,ti,signature = getsig()
    headers = {
        'sys': 'Android',
        'sysVersion': '6.0.1',
        'appVersion': '8.2',
        'appVersionCode': '54',
        'udid': uuid,
        'clientType': 'android',
        'timestamp': ti,
        'signature': str(signature),
        'Host': 'app.suzhou-news.cn',
        'Connection': 'Keep-Alive',
        'Accept-Encoding': 'gzip',
        'User-Agent': 'okhttp/3.9.0'
    }
    #print(headers)
    url = 'https://app.suzhou-news.cn/api/v1/appNews/getBannerNewsList7?page={}&bannerID=11'.format(str(page))
    response = requests.get(url, headers=headers)
    if response.status_code == 200:
        #print(response.text)
        json = response.json()
        for item in json.get('info'):
            # print(item)
            id = item.get('id')
            result = parse_html(headers, id)
            for i in result:
                # print(i)
                save_to_mongo(i)

def parse_html(headers, id):
    """获取详细文章页面"""
    uuid,ti,signature = getsig()
    url = 'https://app.suzhou-news.cn/api/v1/appNews/getNewDetail?udid={}&id={}'.format(headers['udid'], id)
    # print(url)
    response = requests.get(url, headers=headers)
    if response.status_code == 200:
        # print(response.text)
        json = response.json().get('info')
        yield {
            'id': json.get('id'),
            #'url': url,
            'created_at': json.get('created_at'),
            'title': json.get('title'),
            'read_contents': json.get('read_contents')
        }

def getsig():
    """生成signature参数,并返回uuid,ti,encry_sig"""
    try:
        uuid = str(uuid0.generate())
        ti = str(int(time.time()))
        ori_sig = uuid + "&&" + ti + "&&" + "f1190aca-d08e-4041-8666-29931cd89dde"
        # 将类实例化对象
        JDClass = JClass("MySig")
        jd = JDClass()
        # 调用m11218a方法
        encry_sig = jd.get_sig(ori_sig)
        java.lang.System.out.println(encry_sig)
        #print(encry_sig)
        return uuid,ti,encry_sig
    except Exception as e:
        print(e)

def save_to_mongo(data):
    """将文章存到数据库"""
    # 根据url的id为主键
    if db[MONGO_DB].update({'id': data['id']}, {'$set': data}, True):
        print('Saved to Mongo', data['title'])
    else:
        print('Saved to Mongo Failed', data['title'])

def run():
    """程序入口"""
    try:
        # 实例化一个Java虚拟机
        jvmpath = getDefaultJVMPath()
        # jar路径
        jarpath = "D:/MySig/MySig.jar"
        # 应该是启动虚拟机
        startJVM(jvmpath, "-ea", "-Djava.class.path=%s" % jarpath)
        #print("aa", "-Djava.class.path=%s" % jarpath)
        for i in range(1, 100):
            get_page(i)
    except Exception as e:
        print(e)
        
if __name__ == "__main__":
    run()
    # 关闭虚拟机,必须放在代码最后
    shutdownJVM()

运行脚本看下结果。

image.png

image.png

整个抓取过程就是这样。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值