资讯专栏INFORMATION COLUMN

对Soul 安卓App的一次 api请求 抓取记录

Scott / 4277人阅读

之前注册玩过一段时间的社交app--soul,发现其没有网页版也没有桌面版,app里也没有相关的数据导出功能,作为一个老用户,很多日常发布的瞬间很想导出来,作为纪念,所以就想看看能不能脚本抓取我的数据,才有了下面的记录:

一.对soul抓包

分析Soul App的数据请求,需要用到工具对app应用进行抓包

0 - 工具:Fillder(直接下载安装)
1 - 设置手机和电脑连接的wifi代理,具体步骤可以参考《使用fiddler对手机APP进行抓包》
2 - 打开Fillder,对soul 的数据请求api进行跟踪,抓到下面的请求:

1. 请求Header

其中有几个主要的header :
api-sign : 请求签名(由一个 字符串,UUID(替换"-"为""),时间戳 三个参数通过类c的
public static String a(aa paramaa, String paramString, long paramLong)
方法生成)
requeust-nonce:由UUID.randomUUID().toString().replaceAll("-", "")生成, 生成api-sign签名的参数之一,String类型的UUID
X-Auth-UserId:用户的ID(固定不变)
X-Auth-Token:用户身份认证Token(固定不变)
app-time:时间戳
其他的几个如上图所示,基本不会变化

2.响应body

如图所示,如果请求成功,返回的是一个json数据
失败的话就是:{"code":9000003,"message":"您传递的信息有误,请仔细检查后重试","data":null,"success":false}

以上基本的抓包,可以知道现在需要的是api-sign的生成方法是怎样的,然后根据自己的ID和token组合header进行爬取的请求伪造。但官方没有公开API调用文档,所以只有下载soul app的apk文件,进行反编译查看源码

二、反编译apk查找api签名规则

1.反编译工具

0 - dex2jar(直接下载)
1 - jd-GUI(直接下载,是一个可执行的jar文件)
2 - soul 安卓版的apk

2.使用步骤

0 - 使用系统解压软件直接对apk文件解压,获得文件夹目录,其中包含了classes.dex的类似文件,dex文件是Android虚拟机上面可以执行的文件,jar文件其实就是java的class文件,解压后如下图:

1 - 下载dex2jar后解压,将后缀为.dex的classes文件拷贝到dex2jar的目录下,使用DOS的cmd进入到该目录,使用命令:

d2j-dex2jar  classes.dex

对dex文件进行转换为jar文件,该文件包含了soul App的java源码:

2 - 使用jd-GUI查看jar文件的java源码:
直接将classes2-dex2jar.jar 文件拖入到JD-GUI界面中,查找关键词"api-sign"便可找到生成请求header的类及方法:

生成api-sign的方法:

  public static String a(aa paramaa, String paramString, long paramLong)
  {
    localStringBuilder = new StringBuilder();
    localStringBuilder.append(paramaa.a().a().getPath());
    HashMap localHashMap = new HashMap();
    Object localObject1 = new ArrayList();
    int i = 0;
    try
    {
      Object localObject2;
      while (i < ((s)paramaa.d()).a())
      {
        localObject2 = (s)paramaa.d();
        String str2 = ((s)localObject2).a(i);
        localHashMap.put(str2, ((s)localObject2).c(i));
        ((List)localObject1).add(str2);
        i += 1;
      }
      localObject1 = (String[])((List)localObject1).toArray(new String[0]);
      Arrays.sort((Object[])localObject1, String.CASE_INSENSITIVE_ORDER);
      if (localHashMap.size() != 0)
      {
        int j = localObject1.length;
        i = 0;
        while (i < j)
        {
          localObject2 = localObject1[i];
          if (!bw.a((CharSequence)localHashMap.get(localObject2))) {
            localStringBuilder.append((String)localObject2).append(URLDecoder.decode((String)localHashMap.get(localObject2), "Utf-8"));
          }
          i += 1;
        }
      }
      String str1;
      return f.b(localStringBuilder.toString()).toUpperCase();
    }
    catch (Exception localException1)
    {
      paramaa = paramaa.a();
      if (paramaa.q() > 0)
      {
        i = 0;
        for (;;)
        {
          if (i < paramaa.q())
          {
            str1 = paramaa.a(i);
            localObject1 = paramaa.b(i);
            if ((!bw.a(str1)) && (!bw.a((CharSequence)localObject1))) {}
            try
            {
              localObject2 = URLDecoder.decode(((String)localObject1).replaceAll("%(?![0-9a-fA-F]{2})", "%25"), "utf-8");
              localStringBuilder.append(str1).append((String)localObject2);
              i += 1;
            }
            catch (Exception localException3)
            {
              for (;;)
              {
                try
                {
                  localStringBuilder.append(str1).append((String)localObject1);
                }
                catch (Exception localException2) {}
              }
            }
          }
        }
      }
      localStringBuilder.append(UTDevice.getUtdid(SoulApp.b()));
      localStringBuilder.append("10000003");
      localStringBuilder.append(SoulApp.b().a().getAuthKey());
      localStringBuilder.append(a(paramLong));
      localStringBuilder.append(paramString);
      localStringBuilder.append("3.0.15".replaceAll(".", ""));
      j.a("genSign = :" + localStringBuilder.toString());
    }
  }
三、后续

后续有时间再把整个源码看一遍。。毕竟还是代码量不小。。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/77168.html

相关文章

  • 研发手Q推广遇到的一系列问题

    摘要:第一次做和手对接的项目,虽然只是做一个静态页面,但是遇到的问题无数,分享出来,做个记录。项目需求,做一个静态页面,为导流,要求记录号,为后续分析准备,页面访问量使用统计,页面要能够分享。 第一次做和手Q对接的项目,虽然只是做一个静态页面,但是遇到的问题无数,分享出来,做个记录。项目需求,做一个静态页面,为APP导流,要求记录QQ号,为后续分析准备,页面访问量使用MTA统计,页面要能够分...

    Soarkey 评论0 收藏0
  • 如何用Python抓抖音上的小姐姐

    摘要:比如分钟破译朋友圈测试小游戏文章里用的方法但有些根本就没有提供网页端,比如今年火得不行的抖音。所以常用的方式就是通过在电脑上装一些抓包软件,将手机上的网络请求全部显示出来。总结下,重点是的抓取,关键是配置代理证书,难点是对请求的分析。 爬虫的案例我们已讲得太多。不过几乎都是 网页爬虫 。即使有些手机才能访问的网站,我们也可以通过 Chrome 开发者工具 的 手机模拟 功能来访问,以便...

    FingerLiu 评论0 收藏0
  • 初步整理的关于 Progressive Web Apps 的资料

    摘要:在上看到发的视频被狂转开始注意之前几乎对这个词语没有印象看到是在的演讲还以为是新技术在上找一下这次好多个视频是关于的视频的内容主要是讲网站优化分别用做例子可惜没有大概要等小右补方案应该没有问题从视频看优化的效果非常显著本来好几秒的 在 Twitter 上看到 Addy Osmani 发的视频被狂转, 开始注意https://twitter.com/addyosmani/status/7...

    luffyZh 评论0 收藏0
  • 爬虫问题总结

    摘要:编码我们发现,中有时候存在中文,这是就需要对进行编码。可以先将中文转换成编码,然后使用方法对参数进行编码后传递。 本文档对日常学习中用 python 做数据爬取时所遇到的一些问题做简要记录,以便日后查阅,部分问题可能因为认识不到位会存在一些误解,敬请告知,万分感谢,共同进步。 估算网站规模 该小节主要针对于整站爬取的情况。爬取整站之前,肯定是要先对一个网站的规模进行估计。这是可以使用g...

    nanfeiyan 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<