开开心心爬APP,结果一坑连一坑
本文来自「凹凸数据」读者投稿,欢迎大家分享更多优质内容!奖励多多~
最近因为业务需求,而要爬的数据又刚好没有对应的网页版,使我对手机爬虫教程格外感兴趣,一顿操作之后我发现,在这个过程中我遇到了一些回避不了的坑,需要跟大家分享一下。
前文回顾
回顾一下这篇文章用Fiddler篇爬取APP的教程:抓包手机大致分为以下几步(具体的大家可以回顾对不起,我把APP也给爬了):
安装软件,设置软件。同时在电脑上安装证书
用手机连上和电脑相同的WIFI后,手机端设置代理。
手机端安装证书,信任证书。
打开抓包软件,刷新手机数据,观察并查找对应url。
一般来说,照这几个步骤是能够很顺利的取到数据。但是总有人脸黑,比如我。无论是用Fiddler还是Charles,都只能打开浏览器和高德地图。而打开知乎,小红书,好好住等APP却一律被拒绝访问。(oppo和小米手机都尝试过。)
尽管并非所有人都会踩到这个坑,但是这种进行到90%却突然卡住的感觉真的非常膈应人,查了好几篇博客,比较靠谱的说法是:Android7以后,APP一般不信任用户自己安装的凭据,也就是我们在手机上安装的抓包软件证书。
解决方法有两个:
方法一,用Xposed拦截对证书的验证。 方法二、把Fiddler/Charles的证书放进系统的证书目录里。
第一种方法仍然有坑,手机能检测到xposed拦截终还是会失败(这里我没有验证过,有兴趣的同学可以试试)。所以我选择planB,这里写下我的过程,作为一份补充参考给大家。
Charles的配置与步骤
在正餐开始之前,我简单说下Charles的配置(和Fiddler一个逻辑。只是界面稍有不同,选择用Fiddler的同学可以跳过这里直接看后面)
Charles的配置
1、软件安装基本上就是一路Next,装好以后进入主界面,进行如下设置:
2、在PC端安装证书,放置到受信任的机构。
3、打开手机的浏览器,输入弹窗中提示的链接chls.pro/ssl,下载证书安装。
好了,到这里重点来了!
同学们,如果你该勾选的选项也勾选了,该安装的证书也安装了,端口和代理配置都么有问题,以及最重要的是,如果你在电脑端能抓到数据,手机APP却拒绝访问。
别怀疑,你一定是碰到和我一样的坑了:你的手机APP不信任你安装的Charles/fiddler证书。我们需要想办法把它放到系统证书目录中去。
正餐开始。
当然,在开始之前,你需要准备:
一台root过的安卓机(最好是备用机,我用的是小米)
Charles或者Fiddler的证书文件(Charles是crt文件,Fiddler是cer文件,后面获取hash值的时候会有差别)
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 Zhengshu
openssl 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 requests
import time
import 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())
脸黑的朋友们可以考虑下试试我的方法,也许能够解决困扰了你很久的问题。