大师兄的Python学习笔记(二十七): 爬虫(八)

大师兄的Python学习笔记(二十六): 爬虫(七)
大师兄的Python学习笔记(二十八): 爬虫(九)

九、爬取APP

  • 在没有网页端的情况下,可以通过爬取App获取数据。
  • APP的反爬虫措施没有那么强,且数据通常是Json格式,所以爬起来可能比web端更简单。
  • 常用抓包软件包括:WireShark、Fiddler、Charles、mitmproxy、AnyProxy...
  • 可以使用Appium对APP进行自动化控制。
9.1 关于Charles
  • Charles是一种网络抓包工具,可以获取App运行过程中发生的所有网络请求和相应内容。
  • 可以作为主要的移动端抓包工具,用于抓包分析。
9.1.1 安装Charles

第一步:下载Charles
官网点此处下载安装30天试用版。

大师兄的Python学习笔记(二十七): 爬虫(八)_第1张图片

大师兄的Python学习笔记(二十七): 爬虫(八)_第2张图片

第二步:安装PC端Https证书
大师兄的Python学习笔记(二十七): 爬虫(八)_第3张图片

大师兄的Python学习笔记(二十七): 爬虫(八)_第4张图片

大师兄的Python学习笔记(二十七): 爬虫(八)_第5张图片

第三步:安装手机端Https证书

  • 首先将电脑和手机接入同一个局域网中。
  • PC端设置代理并开启。


    大师兄的Python学习笔记(二十七): 爬虫(八)_第6张图片
  • 手机端接入PC端代理。


    大师兄的Python学习笔记(二十七): 爬虫(八)_第7张图片
  • PC端同意接入。


    大师兄的Python学习笔记(二十七): 爬虫(八)_第8张图片
  • 手机端访问http://www.charlesproxy.com/getssl下载证书。
  • 下载后在手机端安装证书: 加密和凭据->从存储设备安装
    大师兄的Python学习笔记(二十七): 爬虫(八)_第9张图片
    image.png

    第四步:配置SSL监听
    大师兄的Python学习笔记(二十七): 爬虫(八)_第10张图片
9.1.2 Charles抓包
  • 首先确保http和https监听都已经开启。


  • 可以考虑将Proxy->Windows Proxy关掉,以便观察手机端数据。
  • 用手机打开京东app,并随便打开一件商品。


  • 观察PC端Charles抓取到的数据,包括表单和Json格式的数据都已经抓到了。


    大师兄的Python学习笔记(二十七): 爬虫(八)_第11张图片
9.2 关于mitmproxy
  • mitmproxy是与Charles类似的抓包程序,但是控制台形式。
  • mitmproxy有两个关联组件,分别是mitmdump和mitmweb。
  • mitmdump是命令行接口,可以用来对接Python。
  • mitmweb是web程序。
9.2.1 安装mitmproxy
  • 安装mitmproxy非常简单,只需要使用pip install mitmproxy就可以安装mitmproxy、mitmdump和mitmweb。
9.2.2 获取https证书
  • 与charles一样,如果想截取https请求,则需要设置证书。
  • 谷歌在安卓7.0修改了安全策略,用户添加的CA证书不能再用于安全连接,苹果手机可以正常爬取。

第一步:使用mitmdump指令启动mitmdump并生成证书。


第二步: 找到并双击认证mitmproxy-ca-cert.p12证书文件。
大师兄的Python学习笔记(二十七): 爬虫(八)_第12张图片

大师兄的Python学习笔记(二十七): 爬虫(八)_第13张图片

第三步: 将证书文件mitmproxy-ca-cert.pem发送到手机端并验证。
大师兄的Python学习笔记(二十七): 爬虫(八)_第14张图片

9.2.3 手机端配置代理
  • 在局域网配置->代理中配置mitmproxy主机的ip地址和port。


    大师兄的Python学习笔记(二十七): 爬虫(八)_第15张图片
9.2.4 使用mitmproxy抓取数据
  • 手机端完成代理配置后,就可以启动mitmproxy服务了


  • 测试访问页面。


  • 如果你用的是windows,也可以使用mitmweb使用网页版抓取数据。



    大师兄的Python学习笔记(二十七): 爬虫(八)_第16张图片
9.2.5 使用mitmdump对接Python
  • mitmdump是mitmproxy的命令行对接口,同时也可以对接Python处理请求,这是mitmproxy相比charles的优势。
  • 可以添加参数,如mitmdump -s script.py使用Python脚本处理截获的数据。
  • 此外,在控制台使用mitmdump -h可以查看所有参数,其中比较常用的有:

-p port: 改变端口
-s script.py: 使用脚本处理截获数据
-w outfile : 将截获数据保存到文件

  • 在Python脚本端,可以使用mitmproxy包处理截获的数据,mitmproxy.http.HTTPFlow常用接口如下:
接口 作用
flow.request.headers 获取所有头信息,包含Host、User-Agent、Content-type等字段
flow.request.pretty_url 完整的请求地址,包含域名及请求参数,但是不包含放在body里面的请求参数
flow.request.host 域名
flow.request.method 请求方式。POST、GET等
flow.request.scheme 什么请求 ,如https
flow.request.path 请求的路径,url除域名之外的内容
flow.request.get_text() 请求中body内容,有一些http会把请求参数放在body里面,那么可通过此方法获取,返回字典类型
flow.request.query MultiDictView类型的数据,url直接带的键值参数
flow.request.get_content() bytes,结果如flow.request.get_text()
flow.request.raw_content bytes,结果如flow.request.get_content()
flow.request.urlencoded_form MultiDictView,content-type:application/x-www-form-urlencoded时的请求参数,不包含url直接带的键值参数
flow.request.multipart_form MultiDictView,content-type:multipart/form-data时的请求参数,不包含url直接带的键值参数
flow.response.status_code 返回状态码
flow.response.text 返回内容,已解码
flow.response.content 返回内容,二进制
flow.response.setText() 修改返回内容,不需要转码
  • 示例:
>>>from mitmproxy import http

>>>def request(flow):
>>>    if flow.request.pretty_url == "http://httpbin.org/get":
>>>        flow.response = http.HTTPResponse.make(
>>>            200,
>>>            b'Hello World!',
>>>            {"Content-Type":"text/html"}
>>>        )

大师兄的Python学习笔记(二十七): 爬虫(八)_第17张图片
9.3 关于Appium
  • Appium是一个跨平台移动端自动化测试工具,可以看成是Andriod或IOS端的Selenium。
  • 能够在模拟App内部的各种操作,比如点击、滑动、输入等。
9.3.1 安装Appium
  • 点击此处下载Appium。

    大师兄的Python学习笔记(二十七): 爬虫(八)_第18张图片

  • 如果需要用安卓手机抓取,则点击此处下载Android Studio。

  • 安装Andriod Studio后继续安装Android SDK。


    大师兄的Python学习笔记(二十七): 爬虫(八)_第19张图片
  • 配置Android SDK环境变量。


    大师兄的Python学习笔记(二十七): 爬虫(八)_第20张图片
  • 如果使用IOS爬取数据,则需要在mac电脑上执行xcode-select --install配置环境。

9.3.2 启动Appium

第一步:打开Appium界面,默认端口为4723。

大师兄的Python学习笔记(二十七): 爬虫(八)_第21张图片

第二步:配置ANDROID_NAME并点击Start Server启动服务器。
大师兄的Python学习笔记(二十七): 爬虫(八)_第22张图片

大师兄的Python学习笔记(二十七): 爬虫(八)_第23张图片

第三步:将手机连接数据线,并打开USB调试功能,通过adb指令检查设备是否匹配成功。

第四步:点击Appium界面的Start Inspector Session按键。
大师兄的Python学习笔记(二十七): 爬虫(八)_第24张图片

第五步:找到appPackage和appActivity。

  • 在cmd使用adb logcat指令
  • 手机端打开app
  • 查看log.txt


    大师兄的Python学习笔记(二十七): 爬虫(八)_第25张图片

第六步:配置Desired Capablilities中的platformName(平台名)、deviceName(设备名)、appPackage(程序包名)和appActivity(入口Activity名)

大师兄的Python学习笔记(二十七): 爬虫(八)_第26张图片

第七步:点击Start Session按钮

  • 如果一切顺利,不仅手机进入启动界面,同时调试窗口会显示页面源码。


    大师兄的Python学习笔记(二十七): 爬虫(八)_第27张图片
  • 不仅如此,还可以对元素进行操作,比如点击、输入、拖拽等。


    大师兄的Python学习笔记(二十七): 爬虫(八)_第28张图片
9.3.3 用Python驱动Appium
  • 以豆瓣app为例。
  • 首先使用pip install appium-python-client安装appium包。
  • 确保appium server处于开启状态。
>>>from appium import webdriver
>>>from selenium.webdriver.common.by import By
>>>from selenium.webdriver.support.ui import WebDriverWait
>>>from selenium.webdriver.support import expected_conditions as EC

>>>server = 'http://localhost:4723/wd/hub' # 服务器地址

>>>desired_caps = {
>>>    # 配置desired参数
>>>    "platformName": "Android",
>>>    "deviceName": "HUAWEI_mate30_pro",
>>>    "appPackage": "com.douban.frodo",
>>>    "appActivity": ".activity.SplashActivity"
>>>}

>>>driver = webdriver.Remote(server,desired_caps) # 启动APP
>>>wait = WebDriverWait(driver,30)

>>>next = wait.until(EC.presence_of_all_elements_located((By.ID,'com.douban.frodo:id/next')))[0]
>>>next.click() # 点击下一步

>>>prim_confirm = wait.until(EC.presence_of_all_elements_located((By.ID,'android:id/button1')))[0]
>>>prim_confirm.click() # 确认给予权限
>>>cancel_login = wait.until(EC.presence_of_all_elements_located((By.ID,'com.douban.frodo:id/close')))[0]
>>>cancel_login.click() # 为了方便演示,这里就先不登录了

>>># 切换tap刷新页面
>>>tap_2 = wait.until(EC.presence_of_all_elements_located((By.ID,'com.douban.frodo:id/icon')))[1]
>>>tap_2.click()
>>>tap_1 = wait.until(EC.presence_of_all_elements_located((By.ID,'com.douban.frodo:id/icon')))[0]
>>>tap_1.click()

>>># 获取推荐内容
>>>contents = wait.until(EC.presence_of_all_elements_located((By.ID,'com.douban.frodo:id/status_text')))

>>>for content in contents:
>>>    print(content.get_attribute("text"))
现在都懒得攒着,随手扔了

参考资料


  • https://blog.csdn.net/u010138758/article/details/80152151 J-Ombudsman
  • https://www.cnblogs.com/zhuluqing/p/8832205.html moisiet
  • https://www.runoob.com 菜鸟教程
  • http://www.tulingxueyuan.com/ 北京图灵学院
  • http://www.imooc.com/article/19184?block_id=tuijian_wz#child_5_1 两点水
  • https://blog.csdn.net/weixin_44213550/article/details/91346411 python老菜鸟
  • https://realpython.com/python-string-formatting/ Dan Bader
  • https://www.liaoxuefeng.com/ 廖雪峰
  • https://blog.csdn.net/Gnewocean/article/details/85319590 新海说
  • https://www.cnblogs.com/Nicholas0707/p/9021672.html Nicholas
  • https://www.cnblogs.com/dalaoban/p/9331113.html 超天大圣
  • https://blog.csdn.net/zhubao124/article/details/81662775 zhubao124
  • https://blog.csdn.net/z59d8m6e40/article/details/72871485 z59d8m6e40
  • https://www.jianshu.com/p/2b04f5eb5785 MR_ChanHwang
  • 《Python学习手册》Mark Lutz
  • 《Python编程 从入门到实践》Eric Matthes
  • 《Python3网络爬虫开发实战》崔庆才

本文作者:大师兄(superkmi)

你可能感兴趣的:(大师兄的Python学习笔记(二十七): 爬虫(八))