做爬虫的时候有时需要去采集某些APP内提供的数据,比如各种新闻客户端(腾讯自选股、新浪新闻等),这些不像是web网站,可以直接使用chrome分析对后端的请求。因为是app内调用的,所以需要采用代理的方式,做中间人来获取到app对服务端到请求,从而去分析请求参数信息,最后爬虫来构造类似的请求去获取数据。而现在的app基本上都是用的https协议了, 普通的代理无法直接解析出https的请求信息(包括url, header, response 等等),所以必须使用支持https中间人方式等代理工具才能解析。
现在一般用的比较多的代理工具就是 Charles Proxy了。
今天用这个工具来演示一下如何获取腾讯自选股app中的新闻数据接口。
安装Charles Proxy
可以直接从官网获取到Charles Proxy安装包,支持多种操作系统,我这里下载的是macos版本的。下载地址,特意下载了4.5.1,是因为又这个版本的序列号,无需破解了。
Registered Name: https://zhile.io
License Key: 48891cf209c6d32bf4
安装非常方便,就不截图了。
配置
我这里使用MacOS来做的演示。
要能解析https请求,必须要在客户端安装charles proxy提供的证书,所以配置基本是就是证书的安装了。
- MacOS本机证书安装
打开Charles Proxy工具,界面显示如下
默认启动就开始监听,这个是因为默认勾选了macOS Proxy,然后自动配置好了系统的代理。如下图所示。
另外可以看到https请求的话,只能看到访问的域名信息, 而uri地址信息显示的是unknown,也就是解析不出来。
第一步我们需要在本机安装好证书,第二步,我们需要在Charles Proxy中配置好针对特定站点启用Https Proxying。
按照图中所示,点击Help->SSL Proxying -> Install Charles Root Certificate, 进行根证书的安装。
点击后,可以在“钥匙串访问”app中找到安装的证书。
默认这个证书是不受信任的,双击这个证书可以看到详细信息。
这个时候我们修改他为始终信任。
修改完毕后,显示如下,证明可以了。
这时证书就算安装好了,但是要启用SSL Proxying,还需要在Charles Proxy中针对站点配置SSL Proxying。
两种方式:一种是直接在左侧的列表中,选中你需要解析的https网站,点击右键,选择Enanble SSL Proxying,就可以了。
另外一种是在菜单中点击SSL Proxying Settings,弹出对话框,在这个中去配置好要监听的站点信息。
- iOS证书安装
iOS的证书安装先配置好Charles Proxy提供代理,默认是8888,ip地址可以通过 Help -> Local IP Address 来确认。
具体我就不截图了。 这个一般是连接到同一个wifi,然后在wifi连接中配置代理, 设置好ip,端口就可以了。
然后,用Safari浏览器打开这个地址 http://chls.pro/ssl ,注意这里一定要用Safari浏览器,如果用chrome等浏览器只会下载一个文件,而不是一个描述文件。
按提示下载完毕这个证书描述文件后,在 设置->通用 中会多出一个 描述文件的 菜单,打开这个菜单,选择Charles Proxy CA证书安装好。
然后在 设置 -> 通用 -> 关于本机 -> 证书信任设置 菜单中, 找到Charles Proxy CA(xxxx),点击启用完全信任。
到此,iOS上的证书就算完全安装好了。 接下来,我们就可以针对app进行https包的分析了。
抓包分析
打开“腾讯自选股”app,点击新闻栏目。
Charles Proxy 工具的左侧应该有一些站点列出来了,但是我们不知道哪个是我们要监听的,所以,我们可以先清空所有已经记录的请求(点击那个扫把🧹图标)。
这时,在新闻栏目中下拉一下,让app去请求服务器端。
可以发现有一个snp.tenpay.com的域名,我们右键启用SSL Proxying。(我这里已经启用了)。
然后可以看到已经不是显示 unknown了,而是直接把uri显示出来了。
点击这条具体的URI,右侧会显示详情信息,包括请求头,响应内容等等。可以非常方便的供我们对信息进行分析。
可以看到,我们已经找到了这个新闻列表的地址了,返回的是json数据,可以进行方便的数据解析了。
如果觉得用Charles不方便看响应的内容,我们可以直接把请求地址复制到浏览器中请求,然后查看响应内容。不过有些地址,不能直接在浏览器中访问,因为他会有一些特殊的头信息要传到服务器做验证。这时我们就只能在Charles中分析好,再通过其他工具默认请求了。
构造请求
爬虫的写法有很多方式,这里直接用python的requests演示
import requests
import json
target = "https://snp.tenpay.com/cgi-bin/snpgw_yaowen_recom.fcgi?device_id=e301c81db989fa30c337b0aebb232e28e300107e&zappid=zxg_h5&sign=d8e1eacacad149b02b7c1974dac47bd6&nonce=9647&refresh=1&top_num=0&total_news_num=0&limit=20&tzbd_num=9&reserve=2366095&recom_off=0&_appName=ios&_dev=iPhone13,2&_devId=e301c81db989fa30c337b0aebb232e28e300107e&_appver=9.2.1&_ifChId=&_isChId=1&_osVer=14.6&openid=anonymous&fskey=anonymous&appid=&access_token=anonymous&buildType=store&check=-1&_idfa=&lang=zh_CN"
#尽量使用原装的user-agent
headers = {"user-agent":"QQStock/9.2.1 (iPhone; iOS 14.6; Scale/3.00)", "referer":"http://zixuanguapp.finance.qq.com"}
res = requests.get(target, headers=headers)
body = json.loads(res.text)
评论区