mitmproxy的使用
mitmproxy是一个支持HTTP和HTTPS的抓包程序,有类似Fiddler、Charles的功能,只不过它是一个控制台的形式操作。
mitmproxy还有两个关联组件。一个是mitmdump,它是mitmproxy的命令行接口,利用它我们可以对接Python脚本,用Python实现监听后的处理。另一个是mitmweb,它是一个Web程序,打开它是一个监视网页,我们可以很清楚地观察到mitmproxy捕获的请求。windows不支持mitmproxy命令,可以直接运行mitmweb或者mitmdump。
1.所需环境
Windows安装mitmproxy,并且手机和pc处于同一个局域网(WiFi)下,同时要配置好CA证书。
安装python所需库mitmproxy。
2.mitmproxy的功能
- 拦截HTTP和HTTPS请求
- 保存HTTP会话并进行分析
- 模拟客户端发起请求,模拟服务器返回响应
- 利用反向代理将流量转发给指定服务器
- 利用python对HTTP请求和响应进行实时处理
3.抓包原理
mitm运行在pc的8080端口,在此端口开启一个http/https代理服务。
手机和pc在同一局域网内,手机设置代理为mitmproxy的代理,这样手机在访问互联网的时候流量数据就会流经mitmproxy,mitmproxy再去转发这些数据包到真实服务器。
服务器返回数据包由mitmproxy转发到手机,这样mitmproxy就起到了一个中间人的作用,抓取到所有Request和Response,然后对接python,对抓取到的内容进行解析。
4.mitmweb的使用
windows命令行运行:
C:\Users\Administrator>mitmweb
Web server listening at http://127.0.0.1:8081/
Proxy server listening at http://*:8080
手机与pc处于统一局域网,Windows最好关闭防火墙,命令成功运行后自动打开浏览器进入web交互界面。或者手动访问http://127.0.0.1:8081/
设置好mitmproxy,手机浏览器访问网页或者打开app,mitmweb就会出现手机上所有请求。
5.mitmdump的使用
mitmdump是mitmproxy的命令行接口,同时还可以对接python对请求进行处理。有了它我们可以不用手动截获和分析HTTP请求和响应,只需写好请求和响应的处理逻辑即可。它还可以实现数据的解析,存储等工作,这些过程都可以通过python实现。
使用命令启动mitmproxy,并把截获的数据保存到文件。
H:\PycharmProjects\>mitmdump -w outfile Proxy server listening at http://*:8080
outfile为文件名称,文件名任意,截获的数据都会保存到此文件中。
指定一个脚本来处理截获的数据,使用-s参数即可:
mitmdump -s script.py
指定当前处理脚本为script.py,需要放置才当前执行命令的文件夹下。
script.py的代码
def request(flow): #定义一个request方法,参数为flow,它是一个HTTPFlow对象 flow.request.headers['User-Agent']='MitmProxy' #通过request属性即可获取当前请求对象,将请求头改为User-Agent print(flow.request.headers) #输出请求的请求头
运行之后,手机访问http://httpbin.org/get,可以看到User-agent为修改后的值。
在pc控制台也可以看到输出修改后的Headers内容。
日志输出
mitmdump提供了专门的日志输出功能,可以设定不同级别的颜色输出结果。修改脚本的内容:
from mitmproxy import ctx def request(flow): #定义一个request方法,参数为flow,它是一个HTTPFlow对象 flow.request.headers['User-Agent']='MitmProxy' #通过request属性即可获取当前请求对象,将请求头改为User-Agent # 调用ctx模块,它有一个log功能,调用不同的输出方法就可以输出不同颜色的结果 # info()方法输出的内容颜色为白色,warn()为黄色,error()为红色 ctx.log.info(str(flow.request.headers)) ctx.log.warn(str(flow.request.headers)) ctx.log.error(str(flow.request.headers))
Request
前面实现了request()方法对Headers进行了修改。Request的常用功能:
from mitmproxy import ctx def request(flow): request=flow.request info=ctx.log.info info(request.url) info(str(request.headers)) info(str(request.cookies)) info(request.host) info(request.method) info(str(request.port)) info(request.scheme)
运行此脚本,在手机上打开百度,即可看到pc控制台输出一系列请求,也可看到控制台输出Request的一些常见属性,url,headers,cookies,host,method,scheme等。
https://m.baidu.com/tc?tcreq4log=1&r=1579863109862&logid=2728... Headers[(b'Host', b'm.baidu.com'), (b'Connection', b'keep-alive'), (b'User-Agent', b'Mozilla/5.0 (Linux; U; Android 6.0.1; zh-cn; OPPO A57t Build/ MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/66.0.3359.126 MQQBrowser/10.0 Mobile Safari/537.36'), (b'Accept', b'image/webp,i mage/sharpp,image/apng,image/tpg,image/*,*/*;q=0.8'), (b'Referer', b'https://m.baidu.com/?from=1086k'), (b'Accept-Encoding', b'gzip, deflate'), (b 'Accept-Language', b'zh-CN,en-US;q=0.9'), (b'Cookie', b'BAIDUID=B41CBBCB0A75141861A61E19800F4205:FG=1; delPer=0; MSA_WH=360_510; FEED_SIDS=137967_ 1101_16; COOKIE_SESSION=0_0_0_1_0_w3_2_1_2_0_0_1_20_1573220379%7C1%230_0_0_0_0_0_0_0_1573220379%7C1; ZD_ENTRY=baidu; FC_MODEL=-1_6_3_5.42_14.47_7_ 0_19.8_3_0_271.62_-1_4_10_24_5_0_1573220834032_1573220379680%7C9%2314.47_-1_-1_10_1570 ... m.baidu.com GET 443 https
结果分别输出了请求链接,请求头,请求cookies,请求Host,请求方法,请求端口,请求协议。
同时也可以对任意请求进行更改,直接赋值即可。
from mitmproxy import ctx def request(flow): # 对请求进行更改 url='https://httpbin.org/get' flow.request.url=url
手机再次访问百度,浏览器上方虽然还是百度的url,但是下方的页面已经换成httpbin.org的页面。cookies仍然是百度的Cookies。
响应
对于爬虫来说,更重要的还是响应内容,Response Body才是爬取的结果。对于响应,mitmdump提供了对应的处理接口,response()方法,
from mitmproxy import ctx def response(flow): response=flow.response info=ctx.log.info ctx.log.info(str(response.status_code)) info(str(response.headers)) info(str(response.cookies)) info(str(response.text))#网页的源代码
运行此脚本,然后手机访问http://httpbin.org/get,可以看到控制台输出以下内容
200 Headers[(b'Date', b'Sat, 25 Jan 2020 03:54:58 GMT'), (b'Content-Type', b'application/json'), (b'Content-Length', b'819') , (b'Connection', b'keep-alive'), (b'Server', b'gunicorn/19.9.0'), (b'Access-Control-Allow-Origin', b'*'), (b'Access-Con trol-Allow-Credentials', b'true')] MultiDictView[] { "args": {}, "headers": { "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,image/sharpp,image/apng,image /tpg,*/*;q=0.8", "Accept-Encoding": "gzip, deflate", "Accept-Language": "zh-CN,en-US;q=0.9", "Cache-Control": "max-age=0", "Cookie": "pgv_info=ssid=s6343193020; pgv_pvid=7406669290; ts_uid=7440951464", "Host": "httpbin.org", "Proxy-Connection": "keep-alive", "Upgrade-Insecure-Requests": "1", "User-Agent": "Mozilla/5.0 (Linux; U; Android 6.0.1; zh-cn; OPPO A57t Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/66.0.3359.126 MQQBrowser/10.0 Mobile Safari/537.36", "X-Amzn-Trace-Id": "Root=1-5e2bbc12-ab284d4ecb7cd12c716f6066" }, "origin": "223.89.246.68", "url": "http://httpbin.org/get" }
控制台输出了响应的状态码,响应头,Cookies,响应体。通过response()方法获取每个请求的响应内容,再对响应的内容进行提取和存储,就可以成功完成爬取。
爬取得到APP电子书信息
1.爬取目标
爬取得到app内电子书板块的电子书信息,并将信息保存到mongoDB。
把图书的名称,简介,封面,价格爬取下来,主要是对mitmproxy的用法进行练习,不涉及自动爬取。
2.所需环境
安装mitmproxy,手机和pc处于同一局域网下,同时配置好mitmproxy的CA证书,运行pymongo服务以及pyMongo库。
3.抓取分析
首先查看一下当前页面的url和返回内容,编写一个脚本
from mitmproxy import ctx
def response(flow):
print(str(flow.request.url))#输出请求的url
print(str(flow.response.text))#输出响应内容
运行此脚本,在控制台可以看到相应输出。滑动页面加载更多电子书,控制台就会出现新的输出内容就是APP发出的加载请求,包含了下一页的电子书内容。
如果控制台有乱码,不易观察接口的url地址,也可以通过mitmweb进行查看,最终可以看到的接口为:
{
"c": {
"list": [
{
"author": "",
"author_info": "",
"author_list": null,
"authors": [],
...
"book_intro": "如何应对即将到来的阶层社会?\r\n怎么克服自己与生俱来的本能?\r\n如何面对坚固的东西烟消云散?\r\n怎么获得一种面对复杂信息的思维框架?\r\n这个变动的世界里,到底该信谁?\r\n怎么能成为一个高手?\r\n……\r\n\r\n如今,连一个外卖App都在不停升级,学习对我们每个人而言,都不再是过去式、完成时。在这本书里,罗胖将和你继续探索问题的答案。\r\n",
"book_name": "《终身学习》",
...
"cover": "https://piccdn.igetget.com/img/201801/09/201801091204495621516010.jpg",
"current_price": "9.99",
...
"price": "9.99",
"publish_time": "2017-11-01",
"rank": {
"classTitle": "",
"classificationId": 0,
"ranking": 2,
"requestType": "hot_rank"
}
...
},
{
"author": "",
"author_info": "",
"author_list": null,
"authors": [],
...
"book_intro": "你应该去哪里找寻自己的心上人?什么“货币”能够“买”到好伴侣?如何在初次约会时就令对方怦然心动?何时应该欲擒故纵?何时应该主动出击?如何利用两性差异让对方爱上你?如何靠近女人的心灵?如何满足对方内心深处的渴望?\n\n国际著名情感问题专家莉尔·朗兹以坚实的科学研究为基础,通过真实生动的个案,对男女两性在情爱观念与行为上的差异进行了饶有趣味的分析。书中详细描述了男女在情感需求与表达方面的区别,探讨了他们坠入情网的缘由和过程,并由此引导我们通过各种语言以及非语言的方法与技巧,博得意中人的青睐,收获心目中的理想爱情。",
"book_name": "如何让你爱的人爱上你",
...
4.抓取数据
修改上述脚本,其内容为:
from mitmproxy import ctx
import json
def response(flow):
# print(str(flow.request.url))#输出请求的url
# print(str(flow.response.text))#输出响应内容
url='https://entree.igetget.com/ebook2/v1/ebook/list'
if flow.request.url.startswith(url):
text=flow.response.text
data=json.loads(text)
books=data.get('c').get('list')
for book in books:
ctx.log.info(str(book))
滑动电子书页面,在pc控制台观察输出,
192.168.155.2:61151: POST https://entree.igetget.com/ebook2/v1/ebook/list
<< 200 OK 15.99k
{'id': 14529, 'title': '', 'style': 1, 'type': 1, 'class': 0, 'sub_class': 0, 'author': '', 'cover': 'https://piccdn.ige
tget.com/img/201907/24/201907241348379903869831.jpg', 'banner': '', 'count': 0, 'price': '9.90', 'status': 1, 'epub': '2
019', 'sell_count': 0, 'sell_seven_day': 17, 'operating_title': '万历十五年(中华书局修订版)', 'short_title': '', 'inte
gral': 0, 'other_content': '', 'other_share_title': '得到好书 | 万历十五年(中华书局修订版)', 'other_share_summary': '
一部打开中国人视野的经典之作。', 'other_data': '', 'top': 0, 'datetime': '', 'uptime': '', 'drm_epub_size': '11883565',
'author_info': '', 'book_name': '万历十五年(经典本)', 'book_author': '黄仁宇', 'press': ' 中华书局', 'publish_time': '
2014-08-01', 'catalog': '', 'catalog_list': [], 'book_intro': '万历十五年,亦即公元1587年,在西欧历史上为西班牙舰队全部
出动征英的前一年;而在中国,在这平平淡淡的一年中,发生了若干为历史学家所易于忽视的事件。这些事件,表面看来虽似末端小节,
但实质上却是以前发生大事的症结,也是将在以后掀起波澜的机缘。在历史学家黄仁宇的眼中,其间的关系因果,恰为历史的重点,而我
们的大历史之旅,也自此开始。\n\n本书英文本推出后,被美国多所大学采用为教科书,并两次获得美国国家图书奖(American Book Aw
ards)历史类好书的提名;中文本问世后,获得如潮好评,成为众多作家、学者、企业家、高校师生的案头必备书,并入选《新周刊》和
《书城》“改革开放20年来对中国影响最大的20本书”等。另有日文、法文、德文等版本。', 'tts_switch': 1, 'merchant_id': 1430,
'contract_number': '', 'online_time': 1563983897, 'b_special_price': '', 'current_price': '9.90'...
{'id': 2028, 'title': '', 'style': 1, 'type': 1, 'class': 0, 'sub_class': 0, 'author': '', 'cover': 'https://piccdn.iget
get.com/img/201712/28/201712281420073440034671.jpg', 'banner': '', 'count': 0, 'price': '29.40', 'status': 1, 'epub': '2
019', 'sell_count': 0, 'sell_seven_day': 17, 'operating_title': '原则', 'short_title': '', 'integral': 0, 'other_content
': '', 'other_share_title': '得到好书 | 原则', 'other_share_summary': '罗辑思维年度推荐。华尔街投资大神为你解读「算法」
人生。', 'other_data': '', 'top': 0, 'datetime': '', 'uptime': '', 'drm_epub_size': '3885430', 'author_info': '', 'book_
name': '原则', 'book_author': '【美】瑞·达利欧', 'press': '中信出版集团', 'publish_time': '2018-01-01', 'catalog': '',
'catalog_list': [], 'book_intro': '瑞·达利欧是全世界顶级投资家、企业家之一,对冲基金公司桥水创始人。桥水创立至今为客户
赚取的收益远远超过历史上任何一家对冲基金。达利欧认为桥水的成功源自他所奉行的一套原则,而这些原则也是他一生中学到的最重要
的东西。\r\n\r\n达利欧认为,我们可以像看待机器一样看待生活、管理、经商和投资,并将其系统化为一系列原则。这本书阐述了他的
原则的两大基石——极度求真、极度透明,并介绍了以此为基础的创意择优,以及基于可信度评价的决策机制。书中500多条原则将帮助
我们保持开放心态,看清现实,正确评价自己和他人,从容面对做决策、打造强大团队等问题,更进一步深入认识自我,实现不断成长。
\r\n\r\n达利欧相信,自己的成功并非因为个人的特质,而是因为他从失败中学会了做人、做事的原则,而大多数人和公司都可以运用他
的这些原则更好地实现自己的目标。', 'tts_switch': 1, 'merchant_id': 1135, 'contract_number': '', 'online_time': 0, 'b_spe
cial_price': '26.99', 'current_price': '29.40',
....
这样就得到了图书的全部信息,一本图书对应一条json数据。
5.提取保存
提取重要信息,将数据保存到mongoDB数据库。
增加脚本的提取信息和保存信息部分即可。
import json
import pymongo
from mitmproxy import ctx
class Insert_mongo():
def __init__(self):
self.client=pymongo.MongoClient('localhost')
self.db=self.client.igetget
self.collection=self.db.books
def Insert_data(self,data):
self.collection.insert(data)
insert_mogo=Insert_mongo()
def response(flow):
# print(str(flow.request.url))#输出请求的url
# print(str(flow.response.text))#输出响应内容
global insert_mogo #将insert_mogo设置为全局变量
url='https://entree.igetget.com/ebook2/v1/ebook/list'
if flow.request.url.startswith(url):
text=flow.response.text
data=json.loads(text)
books=data.get('c').get('list')
for book in books:
data={
'book_name': book.get('book_name'),
'cover': book.get('cover'),
'summary': book.get('other_share_summary'),
'book_price': book.get('price')
}
ctx.log.info(str(data))
insert_mogo.Insert_data(data)
控制台输出:
192.168.155.2:61675: POST https://entree.igetget.com/ebook2/v1/ebook/list
<< 200 OK 15.99k
{'book_name': '万历十五年(经典本)', 'cover': 'https://piccdn.igetget.com/img/201907/24/201907241348379903869831.jpg',
'summary': '一部打开中国人视野的经典之作。', 'book_price': '9.90'}
{'book_name': '原则', 'cover': 'https://piccdn.igetget.com/img/201712/28/201712281420073440034671.jpg', 'summary': '罗辑
思维年度推荐。华尔街投资大神为你解读「算法」人生。', 'book_price': '29.40'}
{'book_name': '被讨厌的勇气:“自我启发之父”阿德勒的哲学课', 'cover': 'https://piccdn.igetget.com/img/201901/17/2019011
72035047308914281.jpg', 'summary': '《万维钢·精英日课》第三季专题解读,一套强人的生活哲学。', 'book_price': '19.90'}
{'book_name': '穷查理宝典:查理·芒格智慧箴言录', 'cover': 'https://piccdn.igetget.com/img/201701/03/2017010322003022491
98898.jpg', 'summary': '理解商业社会、认识成功本质必读的10本书之一。', 'book_price': '12.99'}
{'book_name': '吃货的生物学修养:脂肪、糖和代谢病的科学传奇', 'cover': 'https://piccdn.igetget.com/img/201803/15/2018031
51847107634245565.jpg', 'summary': '读懂身体里脂肪和糖的秘密,选择适合的饮食方式,让你吃得更好。', 'book_price': '9.90'}
...
查询数据库:
{'_id': ObjectId('5e2bffd069607b8cdfd8f652'), 'book_name': '万历十五年(经典本)', 'cover': 'https://piccdn.igetget.com/img/201907/24/201907241348379903869831.jpg', 'summary': '一部打开中国人视野的经典之作。', 'book_price': '9.90'}
{'_id': ObjectId('5e2bffd069607b8cdfd8f653'), 'book_name': '原则', 'cover': 'https://piccdn.igetget.com/img/201712/28/201712281420073440034671.jpg', 'summary': '罗辑思维年度推荐。华尔街投资大神为你解读「算法」人生。', 'book_price': '29.40'}
{'_id': ObjectId('5e2bffd069607b8cdfd8f654'), 'book_name': '被讨厌的勇气:“自我启发之父”阿德勒的哲学课', 'cover': 'https://piccdn.igetget.com/img/201901/17/201901172035047308914281.jpg', 'summary': '《万维钢·精英日课》第三季专题解读,一套强人的生活哲学。', 'book_price': '19.90'}
...