开开心心爬APP,结果一坑连一坑

三筒 凹凸数据

本文来自「凹凸数据」读者投稿,欢迎大家分享更多优质内容!奖励多多~

大家好,我是新人三筒。
作为凹凸的铁粉,我会经常在历史消息里挖坟寻找我需要的教程。
最近因为业务需求,而要爬的数据又刚好没有对应的网页版,使我对手机爬虫教程格外感兴趣,一顿操作之后我发现,在这个过程中我遇到了一些回避不了的坑,需要跟大家分享一下。

前文回顾


回顾一下这篇文章用Fiddler篇爬取APP的教程:抓包手机大致分为以下几步(具体的大家可以回顾对不起,我把APP也给爬了):

  1. 安装软件,设置软件。同时在电脑上安装证书
  2. 用手机连上和电脑相同的WIFI后,手机端设置代理。
  3. 手机端安装证书,信任证书。
  4. 打开抓包软件,刷新手机数据,观察并查找对应url。
    一般来说,照这几个步骤是能够很顺利的取到数据。但是总有人脸黑,比如我。无论是用Fiddler还是Charles,都只能打开浏览器和高德地图。而打开知乎,小红书,好好住等APP却一律被拒绝访问。(oppo和小米手机都尝试过。)

    尽管并非所有人都会踩到这个坑,但是这种进行到90%却突然卡住的感觉真的非常膈应人,查了好几篇博客,比较靠谱的说法是:Android7以后,APP一般不信任用户自己安装的凭据,也就是我们在手机上安装的抓包软件证书。
    解决方法有两个:
    • 方法一,用Xposed拦截对证书的验证。
    • 方法二、把Fiddler/Charles的证书放进系统的证书目录里。
      第一种方法仍然有坑,手机能检测到xposed拦截终还是会失败(这里我没有验证过,有兴趣的同学可以试试)。所以我选择planB,这里写下我的过程,作为一份补充参考给大家。

      Charles的配置与步骤


在正餐开始之前,我简单说下Charles的配置(和Fiddler一个逻辑。只是界面稍有不同,选择用Fiddler的同学可以跳过这里直接看后面)

Charles的配置

1、软件安装基本上就是一路Next,装好以后进入主界面,进行如下设置:

Proxy》SSL Proxying Settings》Location中Add上Host:,Port:

ProxySettings》Proxies》Port设置为8888(总之手机代理上的端口号要与之相同)
2、在PC端安装证书,放置到受信任的机构。

Help》SSLProxying》InstallCharlesRootCertificate
3、打开手机的浏览器,输入弹窗中提示的链接chls.pro/ssl,下载证书安装。

好了,到这里重点来了!
同学们,如果你该勾选的选项也勾选了,该安装的证书也安装了,端口和代理配置都么有问题,以及最重要的是,如果你在电脑端能抓到数据,手机APP却拒绝访问。
别怀疑,你一定是碰到和我一样的坑了:你的手机APP不信任你安装的Charles/fiddler证书。我们需要想办法把它放到系统证书目录中去。
正餐开始。
当然,在开始之前,你需要准备:

  1. 一台root过的安卓机(最好是备用机,我用的是小米)
  2. Charles或者Fiddler的证书文件(Charles是crt文件,Fiddler是cer文件,后面获取hash值的时候会有差别)
  3. Windows系统需要下载安装openSSL工具(官网:https://www.openssl.org/,安装完后记得把openssl下的bin文件夹目录加入到环境变量中去)
    好了,开始我们的操作!
    step1
    手机端下载证书后先别着急安装,导到电脑上,复制下它的路径(比如我的是"D:\证书\charles\getssl.crt")
    step2
    按Win+R,输入cmd,进入命令窗口,输入:
opensslx509-subject_hash_old-in"D:\证书\charles\getssl.crt"

记得in后面修改为自己的证书路径。执行后我们得到以下内容:

红色的这串就是我们获取到的证书的hash值,这个Hash值记得保存下来。Fiddler的证书由于是cer格式是无法直接获取的,需要先导成crt格式,我会在最后补充
step3

把证书修改成hash值.0格式。如下,别带后缀:

step4
将重命名好的证书放进手机的sd卡,记得复制进去的证书不可以有.crt或者.cer这样的后缀,以.0结尾才对。

step5
把改好名字的证书文件复制到系统的证书目录里,层级稍微有点深,路径如下(我这是小米的路径):

这里就会有个问题出现。直接用系统自带的文件管理器查看的话可能会获取不到完整的system文件目录,建议下载一个RE文件管理器,并且在安全中心里给予它root权限。如下(各品牌手机可能不同):

最后,重启下各类应用,就可以抓取了!

Fiddler的配置与源码


上面都是在说Charles,我们再讲讲Fiddler。

Fiddler的配置

其实Fiddler也是同理,需要我们获取到证书的Hash值,修改证书名后放进系统证书目录。只是因为Fiddler的证书是cer格式,我们需要多一个步骤:先把证书转成crt格式的。
同样是Win+R后输入cmd进入命令窗口。cd到你放置证书的目录,然后输入转换格式的命令。如下(记得你的文件在哪个盘就输入哪个盘,在哪个目录就输入哪个目录):

d:cd Zhengshuopenssl x509 -inform DER -in FiddlerRoot.cer -out FiddlerRoot1.crt

此目录下就会生成一个crt格式的证书,然后我们继续用上面的方法读取它的hash值。输入:

opensslx509-subject_hash_old-in FiddlerRoot.crt

得到我们想要的Hash值

再修改好名字放入系统证书后,我们就可以正常的抓数据了。最后我们以好好住这个APP为例,看看抓下来的数据是什么样的,我们以下面这个话题为例:

多滑动几屏,观察下哪个url是在闪烁的,这个多半就是我们要找的,或者直接从评论里摘取一段话,ctrl+F搜索。这里我们发现是下评论内容都在下面这个url里。

也可以过滤一下监听的信息,在左下角的filter里设置成只监听该网址,看起来会更夹清爽:

好好住这个APP的数据是很清晰的json格式,我们只需要把对应的headers,cookies等参数加上,再写个循环,就能轻松把评论爬下来了。这些信息可以在右上角的窗口观察到,如下:

params参数如下,topic_id对应不同的话题(不过这个id并不是固定不变的,和我上一次观察的不同)

因为本文重点是如何突破APP的防备监听手机数据,这里我们就不详细展开写爬虫的逻辑。

爬虫源码

完整的代码如下。
代码稍微有点丑陋大家不爬这个APP的话可以不用看。

#导入相关模块import requestsimport timeimport random#复制请求头,cookies等参数headers={    'user-agent':'Dalvik/2.1.0 (Linux; U; Android 8.0.0; MI 5 MIUI/8.11.22)hhz4.7.0-did44c043bb9672a88b4eafdfb3ce276c2c-h16946635abc3f22102c7e10-uid597199-ovid_1000000000597199-proxy-emu0',    'accept-encoding':'gzip',    'content-type': 'application/x-www-form-urlencoded',}cookies={    'visitor_token':'ovid_1000000000597199',    'hhz_token':'8ebae5a0dd1c47223a76243ce32f1347',    'Token':'8ebae5a0dd1c47223a76243ce32f1347'}url='https://yapi.haohaozhu.cn/topic/GetAnswerList460'remark_list=[]for i  in range(1,28):    #这个参数虽然又规律但是今天我看的时候已经发生变化了,大家如果要爬的话需要重新观察下。    params='topic_id=365&sort_type=1¤t_time=1589453251&page={}&basic_info=%7B%22%24app_version%22%3A%224.7.0%22%2C%22%24carrier%22%3A%22%E5%85%B6%E4%BB%96%22%2C%22%24lib%22%3A%22Android%22%2C%22%24lib_version%22%3A%221.6.19%22%2C%22%24manufacturer%22%3A%22Xiaomi%22%2C%22%24os%22%3A%22Android%22%2C%22%24os_version%22%3A%228.0.0%22%2C%22%24screen_height%22%3A1920%2C%22%24screen_width%22%3A1080%2C%22distinct_id%22%3A%2244c043bb9672a88b4eafdfb3ce276c2c%22%7D'.format(i)    #注意请求方式是POST    res=requests.post(url,headers=headers,cookies=cookies,params=params)    json_obj=res.json()    data=json_obj['data']    list=data['list']    for content in list:        #把评论文本提取出来        comment_box=content['photo']['photo_info']        comment=comment_box['remark']        remark_list.append(comment)        #加入停顿防止被反爬        time.sleep(random.random())

脸黑的朋友们可以考虑下试试我的方法,也许能够解决困扰了你很久的问题。

©著作权归作者所有:来自51CTO博客作者mb5fe18e5a55d8d的原创作品,如需转载,请注明出处,否则将追究法律责任

更多相关文章

  1. 手机上利用python进行数据分析——创建自己的远程jupyter notebo
  2. PHP以正则表达式验证手机号码
  3. 微信PC端登录和手机端登录逻辑分享
  4. PHP实现手机网站支付(兼容微信浏览器)
  5. 简易实现HTTPS之自签名证书
  6. phpcms如何修改成手机pc自适应
  7. php怎么调用自建证书的webservice
  8. 【Demo见真章】投稿赢HarmonyOS手机Beta公测名额

随机推荐

  1. Golang 可以写游戏吗?
  2. Go 语言和 Java 比较?
  3. Golang 能不能打包为 dll ?
  4. golang可以写网站吗
  5. Golang 免费的吗?
  6. 区块链实战-Hyperledger Fabric(一) 10分钟
  7. Golang 哪个 Web 框架好用?
  8. golang可以做些什么?
  9. Golang 是面向对象还是面向过程?
  10. golang吉祥物是啥?