python爬虫 Appium+mitmdump 京东商品

爬虫系列:http://t.csdnimg.cn/WfCSx

前言

我们知道通过Charles进行抓包可以发现其参数相当复杂,Form 表单有很多加密参数。如果我们只用 Charles 探测到这个接口链接和参数,还是无法直接构造请求的参数,构造的过程涉及一些加密算法,也就无法直接还原抓取过程。

所以我们了解了 mitmproxy 的用法,利用它的 mitmdump 组件,可以直接对接 Python 脚本对抓取的数据包进行处理,用 Python 脚本对请求和响应直接进行处理。这样我们可以绕过请求的参数构造过程,直接监听响应进行处理即可。但是这个过程并不是自动化的,抓取 App 的时候实际是人工模拟了这个拖动过程。如果这个操作可以用程序来实现就更好了。

我们又了解了 Appium 的用法,它可以指定自动化脚本模拟实现 App 的一系列动作,如点击、拖动等,也可以提取 App 中呈现的信息。经过上节爬取微信朋友圈的实例,我们知道解析过程比较烦琐,而且速度要加以限制。如果内容没有显示出来解析就会失败,而且还会导致重复提取的问题。更重要的是,它只可以获取在 App 中看到的信息,无法直接提取接口获取的真实数据,而接口的数据往往是最易提取且信息量最全的。

综合以上几点,我们就可以确定出一个解决方案了。如果我们用 mitmdump 去监听接口数据,用 Appium 去模拟 App 的操作,就可以绕过复杂的接口参数又可以实现自动化抓取了!这种方式应是抓取 App 数据的最佳方式。某些特殊情况除外,如微信朋友圈数据又经过了一次加密无法解析,而只能用 Appium 提取。但是对于大多数 App 来说,此种方法是奏效的。本节我们用一个实例感受一下这种抓取方式的便捷之处。

1. 本节目标

以抓取京东 App 的商品信息和评论为例,实现 Appium 和 mitmdump 二者结合的抓取。抓取的数据分为两部分:一部分是商品信息,我们需要获取商品的 ID、名称和图片,将它们组成一条商品数据;另一部分是商品的评论信息,我们将评论人的昵称、评论正文、评论日期、发表图片都提取,然后加入商品 ID 字段,将它们组成一条评论数据。最后数据保存到 MongoDB 数据库。

2. 准备工作

请确保 PC 已经安装好 Charles、mitmdump、Appium、Android 开发环境,以及 Python 版本的 Appium API。Android 手机安装好京东 App。另外,安装好 MongoDB 并运行其服务,安装 PyMongo 库。具体的配置过程可以参考Python爬虫存储库安装#1-CSDN博客

3. Charles 抓包分析

首先,我们将手机代理设置到 Charles 上,用 Charles 抓包分析获取商品详情和商品评论的接口。

获取商品详情的接口,这里提取到的接口是来自 cdnware.m.jd.com 的链接,返回结果是一个 JSON 字符串,里面包含了商品的 ID 和商品名称。

再获取商品评论的接口,这个过程在前文已提到,在此不再赘述。这个接口来自 api.m.jd.com,返回结果也是 JSON 字符串,里面包含了商品的数条评论信息。

之后我们可以用 mitmdump 对接一个 Python 脚本来实现数据的抓取。

4. mitmdump 抓取

新建一个脚本文件,然后实现这个脚本以提取这两个接口的数据。首先提取商品的信息,代码如下所示:

def response(flow):url = 'cdnware.m.jd.com'if url in flow.request.url:text = flow.response.textdata = json.loads(text)if data.get('wareInfo') and data.get('wareInfo').get('basicInfo'):info = data.get('wareInfo').get('basicInfo')id = info.get('wareId')name = info.get('name')images = info.get('wareImage')print(id, name, images)

这里声明了接口的部分链接内容,然后与请求的 URL 作比较。如果该链接出现在当前的 URL 中,那就证明当前的响应就是商品详情的响应,然后提取对应的 JSON 信息即可。在这里我们将商品的 ID、名称和图片提取出来,这就是一条商品数据。

再提取评论的数据,代码实现如下所示:

# 提取评论数据
url = 'api.m.jd.com/client.action'
if url in flow.request.url:pattern = re.compile('sku\".*?\"(\d+)\"')# Request 请求参数中包含商品 IDbody = unquote(flow.request.text)# 提取商品 IDid = re.search(pattern, body).group(1) if re.search(pattern, body) else None# 提取 Response Bodytext = flow.response.textdata = json.loads(text)comments = data.get('commentInfoList') or []# 提取评论数据for comment in comments:if comment.get('commentInfo') and comment.get('commentInfo').get('commentData'):info = comment.get('commentInfo')text = info.get('commentData')date = info.get('commentDate')nickname = info.get('userNickName')pictures = info.get('pictureInfoList')print(id, nickname, text, date, pictures)

这里指定了接口的部分链接内容,以判断当前请求的 URL 是不是获取评论的 URL。如果满足条件,那么就提取商品的 ID 和评论信息。

商品的 ID 实际上隐藏在请求中,我们需要提取请求的表单内容来提取商品的 ID,这里直接用了正则表达式。

商品的评论信息在响应中,我们像刚才一样提取了响应的内容,然后对 JSON 进行解析,最后提取出商品评论人的昵称、评论正文、评论日期和图片信息。这些信息和商品的 ID 组合起来,形成一条评论数据。

最后用 MongoDB 将两部分数据分开保存到两个 Collection,在此不再赘述。

运行此脚本,命令如下所示:

mitmdump -s script.py

手机的代理设置到 mitmdump 上。我们在京东 App 中打开某个商品,下拉商品评论部分,即可看到控制台输出两部分的抓取结果,结果成功保存到 MongoDB 数据库。

如果我们手动操作京东 App 就可以做到京东商品评论的抓取了,下一步要做的就是实现自动滚动刷新。

5. Appium 自动化

将 Appium 对接到手机上,用 Appium 驱动 App 完成一系列动作。进入 App 后,我们需要做的操作有点击搜索框、输入搜索的商品名称、点击进入商品详情、进入评论页面、自动滚动刷新,基本的操作逻辑和爬取微信朋友圈的相同。

京东 App 的 Desired Capabilities 配置如下所示:

{'platformName': 'Android','deviceName': 'MI_NOTE_Pro','appPackage': 'com.jingdong.app.mall','appActivity': 'main.MainActivity'
}

首先用 Appium 内置的驱动打开京东 App。

这里进行一系动作操作并录制下来,找到各个页面的组件的 ID 并做好记录,最后再改写成完整的代码。参考代码实现如下所示:

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
from time import sleep
​
class Action():def __init__(self):# 驱动配置self.desired_caps = {'platformName': PLATFORM,'deviceName': DEVICE_NAME,'appPackage': 'com.jingdong.app.mall','appActivity': 'main.MainActivity'}self.driver = webdriver.Remote(DRIVER_SERVER, self.desired_caps)self.wait = WebDriverWait(self.driver, TIMEOUT)def comments(self):# 点击进入搜索页面search = self.wait.until(EC.presence_of_element_located((By.ID, 'com.jingdong.app.mall:id/mp')))search.click()# 输入搜索文本box = self.wait.until(EC.presence_of_element_located((By.ID, 'com.jd.lib.search:id/search_box_layout')))box.set_text(KEYWORD)# 点击搜索按钮button = self.wait.until(EC.presence_of_element_located((By.ID, 'com.jd.lib.search:id/search_btn')))button.click()# 点击进入商品详情view = self.wait.until(EC.presence_of_element_located((By.ID, 'com.jd.lib.search:id/product_list_item')))view.click()# 进入评论详情tab = self.wait.until(EC.presence_of_element_located((By.ID, 'com.jd.lib.productdetail:id/pd_tab3')))tab.click()def scroll(self):while True:# 模拟拖动self.driver.swipe(FLICK_START_X, FLICK_START_Y + FLICK_DISTANCE, FLICK_START_X, FLICK_START_Y)sleep(SCROLL_SLEEP_TIME)def main(self):self.comments()self.scroll()
​
if __name__ == '__main__':action = Action()action.main()

代码实现比较简单,逻辑与上一节微信朋友圈的抓取类似。注意,由于 App 版本更新的原因,交互流程和元素 ID 可能有更改,这里的代码仅做参考。

下拉过程已经省去了用 Appium 提取数据的过程,因为这个过程我们已经用 mitmdump 帮助实现了。

代码运行之后便会启动京东 App,进入商品的详情页,然后进入评论页再无限滚动,这样就代替了人工操作。Appium 实现模拟滚动,mitmdump 进行抓取,这样 App 的数据就会保存到数据库中。

6. 结语

以上内容便是 Appium 和 mitmdump 抓取京东 App 数据的过程。有了两者的配合,我们既可以做到实时数据处理,又可以实现自动化爬取,这样就可以完成绝大多数 App 的爬取了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/539461.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring MVC简介及核心组件和调用流程理解

1. Spring MVC简介 Spring Web MVC是基于Servlet API构建的原始Web框架,从一开始就包含在Spring Framework中。正式名称“Spring Web MVC”来自其源模块的名称( spring-webmvc ),但它通常被称为“Spring MVC”。 在控制层框架历…

数据的存储底层详解 - 源码、反码、补码 浮点数的存储

数据的存储 1. 前言2. 数据类型2.1 整形家族2.2 浮点数家族2.3 构造类型(自定义类型)2.4 指针类型2.5 空类型(无类型) 3. 整数在内存中的存储4. 大小端5. 浮点数在内存中的存储 1. 前言 大家好,我是努力学习游泳的鱼。…

html5cssjs代码 018颜色表

html5&css&js代码 018颜色表 一、代码二、效果三、解释 这段代码展示了一个基本的颜色表&#xff0c;方便参考使用&#xff0c;同时也应用了各种样式应用方式。 一、代码 <!DOCTYPE html> <html lang"zh-cn"> <head><title>编程笔记…

Qt 线程池 QThreadPool

一.Qt 线程池 QThreadPool介绍 Qt线程池是一种管理多个线程的并发编程模型&#xff0c;通过使用线程池可以提高性能、控制并发度、提供任务队列和简化线程管理。 在Qt中&#xff0c;线程池的使用主要涉及以下几个步骤&#xff1a; 创建任务类&#xff1a;需要定义一个任务类&am…

利用Java实现数据矩阵的可视化

1. 引言 在进行工程开发时&#xff0c;通常需要在窗口的某个区域将有效数据形象化地呈现出来&#xff0c;例如&#xff1a;对于某一区域的高程数据以伪色彩的方式呈现出高度的变化&#xff0c;这就需要解决利用Java进行数据呈现的问题。本文将建立新工程开始&#xff0c;逐步地…

idea 导入项目

idea 导入项目并运行 导入设置设置 jdk查看maven 设置 导入 在项目首页 或者 file 选择 open, 然后选择项目根路径 设置 设置 jdk 查看maven 设置

8-图像放大

其实&#xff0c;就是开辟一个zoomwidth&#xff0c;zoomheight的内存&#xff0c;再分别赋值即可。 void CDib::Maginify(float xZoom, float yZoom) { //指向原图像指针 LPBYTE p_data GetData(); //指向原像素的指针 LPBYTE lpSrc; //指向缩放图像对应像素的指针 LPBYTE l…

数字化经济的前沿:深入了解 Web3 的商业模式

随着区块链技术的迅速发展&#xff0c;Web3作为一种新型的互联网范式&#xff0c;正逐渐引起人们的关注。它不仅仅是一种技术革新&#xff0c;更是一种商业模式和价值观的转变。本文将深入探讨Web3的商业模式&#xff0c;以及它对数字化经济的影响。 1. 理解Web3的商业模式 We…

智慧楼宇物联网建设实施方案(1)

物联网建设必要性 虽然智慧楼宇现有的信息化建设取得了快速的进步,但信息化手段主要偏重于通信网络设施和IT应用系统,如骨干光网络、语音通信系统、集群通信系统等。但现有的技术手段还不具备成为城市 “神经末梢”的低成本、高可靠性信息化能力。 因此,可适应楼宇强渗透、…

鸿蒙Harmony应用开发—ArkTS声明式开发(容器组件:EffectComponent)

特效合并容器组件&#xff0c;用于子节点特效绘制的合并&#xff0c;实现特效的绘制性能优化。 说明&#xff1a; 该组件从API Version 10开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 该组件为系统接口。 目前该组件仅支持子组件背景…

Claude3、Gemini、Sora与GPT-4:谁将成为AI领域的明日之星?

【最新增加Claude3、Gemini、Sora、GPTs讲解及AI领域中的集中大模型的最新技术】 2023年随着OpenAI开发者大会的召开&#xff0c;最重磅更新当属GPTs&#xff0c;多模态API&#xff0c;未来自定义专属的GPT。微软创始人比尔盖茨称ChatGPT的出现有着重大历史意义&#xff0c;不亚…

学习使用postman软件上传文件发起api接口请求

学习使用postman软件上传文件发起api接口请求 设置headers头信息设置body 设置headers头信息 如图设置&#xff1a; KEY&#xff1a;Content-Type VALUE&#xff1a;multipart/form-data 设置body 设置需要上传的key对应的类型为File&#xff0c;上传类型 设置需要上传的文件…