python3 爬虫实战 :用 Appium 抓取手机 app 的 数据
http://www.ziksp.com/%e5%ad%a6%e4%b9%a0%e8%b5%84%e6%96%99/python%e7%bc%96%e7%a8%8b/ python资料站
From:https://blog.csdn.net/Fan_shui/article/details/81413595
本编教程从 appium 的环境配置开始,到抓取手机 app 微信朋友圈结束。
知乎:https://zhuanlan.zhihu.com/p/41311503
GitHub:https://github.com/FanShuixing/git_webspider
参考博文
appium+python 环境搭建:https://www.cnblogs.com/yoyoketang/p/6128725.html
[Python3网络爬虫开发实战] 1.7.3-Appium的安装:https://cuiqingcai.com/5407.html
java环境配置:https://jingyan.baidu.com/article/fd8044fa2c22f15031137a2a.html
appium 获取 appPackage 和 appActivity : https://blog.csdn.net/mtbaby/article/details/78676477
selenium 动态抓取网页:https://blog.csdn.net/Fan_shui/article/details/81516645
环境搭建
最开始是按照崔大的环境搭建 https://cuiqingcai.com/5407.html,然后弄完之后发现在 notepad 里面写的 python 运行不了,不能打开手机端的 app,appium 倒是可以打开。另外一篇环境搭建的博文安装的 appium 是旧版,我推荐先按照崔大的教程把appium 环境和 Android studio 搭建下载好,重点:我们在安装的时候,安装环境只要是可以改的都改,不要按照默认的下在c 盘,c 盘就那么大个儿,最重要的是要清楚自己的安装位置,后面会用到。(当然也可以直接按照悠悠博主的教程一步步的搭建下来,若是这样,环境搭建下面就都可以不用看了)
我们按照崔大的教程把 appium 环境 和 Android studio 搭建好,其中第三步我再详细加一点,下图是崔大文中的第三步
我的安装位置在F:/SDK
在环境变量中,系统变量下增加一个这样
在系统变量的path中增加个下面两个
弄好后,我们打开另外一篇博文 https://www.cnblogs.com/yoyoketang/p/6128725.html,一步步按照教程来,其中第三步、四步android_sdk下载就不用再下了,崔大的博文中已经下过。(ps:悠悠博主的后面几篇环境搭建也要看)。
如果安装完 Android studio,会自带 把 Android sdk 安装了,可以通过下面步骤找到 sdk 安装路径,然后添加系统环境变量即可
appium 的使用
恭喜恭喜,走到这一步,我走到这儿可是花了好几天的时间。本文使用的真机,没用模拟器,感兴趣的可以搜下模拟器的使用。我们用usb连接上手机,要打开手机上的usb调试,然后输入adb devices -l (不是数字1,是小写 L )
出现上图就证明手机和电脑连接成功,若是出现下图这种,就把手机拔掉再重连一下
成功后,打开appium
platformName:平台名称
deviceName:设备名称,就是刚才的adb devices -l中mode后面就是
appPackage:app包名
appActivity:app活动名
有个简单的方法便可以获得appPackage和appActivity:https://blog.csdn.net/mtbaby/article/details/78676477
start sessions后
我们可以点击左边的登陆(忍不住抱怨下微信,我不就是多登陆了两下,然后微信号被封了一天(*  ̄︿ ̄)),点击登陆后可以看到中间的App Source有高亮的代码,就是这个登陆按钮的,可以再看右边的Selected Element中有Tap、Send keys、Clear。
在最左边图中点击登陆后,若最右边下面的clickable是True,则证明可以点击,可以通过点击Tap实现点击功能,appium就介绍到这。
python对接Appium
首先我们要对接app,就是类似于start session这样的连接
注:代码运行时要保证手机不黑屏
from appium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
PLATFORM='Android'
deviceName='HUAWEI_P7_L09'
app_package='com.tencent.mm'
app_activity='.ui.LauncherUI'
driver_server='http://127.0.0.1:4723/wd/hub'
class Moments():
def __init__(self):
self.desired_caps={
'platformName':PLATFORM,
'deviceName':deviceName,
'appPackage':app_package,
'appActivity':app_activity
}
self.driver=webdriver.Remote(driver_server, self.desired_caps)
self.wait=WebDriverWait(self.driver,300)
def login(self):
print('正在登陆中——————')
def main(self):
self.login()
M = Moments()
M.main()
如果出现 urllib.error.URLError: urlopen error [WinError 10061] 由于目标计算机积极拒绝,无法连接。
看看打开appium没有,打开后再运行上面的代码就没有问题,手机会自动转到微信的登陆界面(注:deviceName要改成自己手机的)
打开微信后,我们要模拟点击登陆按钮,首先要定位到登陆元素,这个跟selenium的用法类似,我们可以打开appium用前面的方式连接微信,也可以打开sdk安装路径下tools中的uiautomatorviewer.bat,第二种方法比较快
下图中,要先点击图中的按钮,才会出现手机上的画面,图中我已经定位到登陆按钮,可以在右边看到属性resource-id,以及clickable=True,确实是可以点击的,为什么要这样确认下呢,因为有的你以为可以点击的元素,也许你定位没有定好,比如说你定位到登陆外更大的一个框,它是不可点击的
from appium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
PLATFORM = 'Android'
deviceName = 'HUAWEI_P7_L09'
app_package = 'com.tencent.mm'
app_activity = '.ui.LauncherUI'
driver_server = 'http://127.0.0.1:4723/wd/hub'
class Moments():
def __init__(self):
self.desired_caps={
'platformName': PLATFORM,
'deviceName': deviceName,
'appPackage': app_package,
'appActivity': app_activity
}
self.driver = webdriver.Remote(driver_server, self.desired_caps)
self.wait = WebDriverWait(self.driver, 300)
def login(self):
print('点击登陆按钮——————')
login = self.wait.until(EC.presence_of_element_located((By.ID, 'com.tencent.mm:id/d75')))
login.click()
def main(self):
self.login()
M = Moments()
M.main()
运行后就会跳出登陆界面,接下来就都是定位元素与点击元素的事情:
from appium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
PLATFORM = 'Android'
deviceName = 'HUAWEI_P7_L09'
app_package = 'com.tencent.mm'
app_activity = '.ui.LauncherUI'
driver_server = 'http://127.0.0.1:4723/wd/hub'
class Moments():
def __init__(self):
self.desired_caps = {
'platformName': PLATFORM,
'deviceName': deviceName,
'appPackage': app_package,
'appActivity': app_activity
}
self.driver = webdriver.Remote(driver_server, self.desired_caps)
self.wait = WebDriverWait(self.driver, 300)
def login(self):
print('点击登陆按钮——————')
login = self.wait.until(EC.presence_of_element_located((By.ID, 'com.tencent.mm:id/d75')))
login.click()
# 输入手机号
phone = self.wait.until(EC.presence_of_element_located((By.ID, 'com.tencent.mm:id/hz')))
phone_num = input('请输入手机号')
phone.send_keys(phone_num)
print('点击下一步中')
button = self.wait.until(EC.presence_of_element_located((By.ID, 'com.tencent.mm:id/alr')))
button.click()
pass_w = input('请输入密码:')
password = self.wait.until(EC.presence_of_element_located((By.ID, 'com.tencent.mm:id/hz')))
password.send_keys(pass_w)
login = self.driver.find_element_by_id('com.tencent.mm:id/alr')
login.click()
# 提示 叉掉
tip = self.wait.until(EC.element_to_be_clickable((By.ID, 'com.tencent.mm:id/an2')))
tip.click()
def main(self):
self.login()
M = Moments()
M.main()
现在已经进入到微信了,我们需要先定位到微信下面的 发现->朋友圈
from appium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import time
PLATFORM = 'Android'
deviceName = 'HUAWEI_P7_L09'
app_package = 'com.tencent.mm'
app_activity = '.ui.LauncherUI'
driver_server = 'http://127.0.0.1:4723/wd/hub'
class Moments():
def __init__(self):
self.desired_caps = {
'platformName': PLATFORM,
'deviceName': deviceName,
'appPackage': app_package,
'appActivity': app_activity
}
self.driver = webdriver.Remote(driver_server, self.desired_caps)
self.wait = WebDriverWait(self.driver, 300)
def login(self):
print('点击登陆按钮——————')
login = self.wait.until(EC.presence_of_element_located((By.ID, 'com.tencent.mm:id/d75')))
login.click()
# 输入手机号
phone = self.wait.until(EC.presence_of_element_located((By.ID, 'com.tencent.mm:id/hz')))
phone_num = input('请输入手机号')
phone.send_keys(phone_num)
print('点击下一步中')
button = self.wait.until(EC.presence_of_element_located((By.ID, 'com.tencent.mm:id/alr')))
button.click()
pass_w = input('请输入密码:')
password = self.wait.until(EC.presence_of_element_located((By.ID, 'com.tencent.mm:id/hz')))
password.send_keys(pass_w)
login = self.driver.find_element_by_id('com.tencent.mm:id/alr')
login.click()
# 提示 叉掉
tip = self.wait.until(EC.element_to_be_clickable((By.ID, 'com.tencent.mm:id/an2')))
tip.click()
def enter(self):
print('点击发现——')
tab = self.wait.until(EC.element_to_be_clickable((By.XPATH, '//*[@resource-id="com.tencent.mm:id/cdh"]/..')))
print('已经找到发现按钮')
time.sleep(6)
tab.click()
# self.wait.until(EC.text_to_be_present_in_element((By.ID,'com.tencent.mm:id/cdj'),'发现'))
print('点击朋友圈')
friends = self.wait.until(EC.presence_of_element_located(
(By.XPATH, '//*[@resource-id="android:id/list"]/*[@class="android.widget.LinearLayout"][1]')))
friends.click()
def main(self):
self.login()
self.enter()
M = Moments()
M.main()
都是些元素定位,多用几次就会了。接下来我们可以提取数据了
from appium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import time
import pymongo
PLATFORM = 'Android'
deviceName = 'HUAWEI_P7_L09'
app_package = 'com.tencent.mm'
app_activity = '.ui.LauncherUI'
driver_server = 'http://127.0.0.1:4723/wd/hub'
class Moments():
def __init__(self):
self.desired_caps = {
'platformName': PLATFORM,
'deviceName': deviceName,
'appPackage': app_package,
'appActivity': app_activity
}
self.driver = webdriver.Remote(driver_server, self.desired_caps)
self.wait = WebDriverWait(self.driver, 300)
self.client = pymongo.MongoClient()
self.db = self.client.weixin
self.collection = self.db.weixin
def login(self):
print('点击登陆按钮——————')
login = self.wait.until(EC.presence_of_element_located((By.ID, 'com.tencent.mm:id/d75')))
login.click()
# 输入手机号
phone = self.wait.until(EC.presence_of_element_located((By.ID, 'com.tencent.mm:id/hz')))
phone_num = input('请输入手机号:')
phone.send_keys(phone_num)
print('点击下一步中')
button = self.wait.until(EC.presence_of_element_located((By.ID, 'com.tencent.mm:id/alr')))
button.click()
pass_w = input('请输入密码:')
password = self.wait.until(EC.presence_of_element_located((By.ID, 'com.tencent.mm:id/hz')))
password.send_keys(pass_w)
login = self.driver.find_element_by_id('com.tencent.mm:id/alr')
login.click()
# 提示 叉掉
tip = self.wait.until(EC.element_to_be_clickable((By.ID, 'com.tencent.mm:id/an2')))
tip.click()
def enter(self):
print('点击发现——')
tab = self.wait.until(EC.element_to_be_clickable((By.XPATH, '//*[@resource-id="com.tencent.mm:id/cdh"]/..')))
print('已经找到发现按钮')
time.sleep(6)
tab.click()
# self.wait.until(EC.text_to_be_present_in_element((By.ID,'com.tencent.mm:id/cdj'),'发现'))
print('点击朋友圈')
friends = self.wait.until(EC.presence_of_element_located(
(By.XPATH, '//*[@resource-id="android:id/list"]/*[@class="android.widget.LinearLayout"][1]')))
friends.click()
def crawl(self):
while True:
items = self.wait.until(EC.presence_of_all_elements_located(
(By.XPATH, '//*[@resource-id="com.tencent.mm:id/dja"]//*[@class="android.widget.FrameLayout"]')))
self.driver.swipe(300, 1000, 300, 300)
for item in items:
try:
nickname = item.find_element_by_id('com.tencent.mm:id/as6').get_attribute('text')
print(nickname)
content = item.find_element_by_id('com.tencent.mm:id/dkf').get_attribute('text')
print(content)
data = {'nickname': nickname, 'content': content}
self.collection.update({'nickname': nickname, 'content': content}, {'$set': data}, True)
except BaseException as e:
print(e)
def main(self):
self.login()
self.enter()
self.crawl()
M = Moments()
M.main()
driver.swipe() 是从点 A 滑动到点 B,driver.swipe(300,1000,300,300)是从点(300,1000)滑动到(300,300)
self.collection.update({'nickname':nickname,'content':content},{'$set':data},True)
首先根据昵称和正文来查询,如果信息不存在,则插入数据,否则更新数据,关键点是第三个参数True,这可以实现存在即更新,不存在即插入的代码,用着感觉很舒服呢
总的来说,感觉学appium挺不容易的,开头就有个环境配置,后面再加上appium对接python的时候超级慢,调试要等很久,再加上微信次数登多了会被封一天,所以这篇教程花了很多时间,在这段时间内下一篇mitmdump都已经诞生了………
如有错误,欢迎指正~
python3 爬虫实战 :用 Appium 抓取手机 app 的 数据相关推荐
- python3 爬虫实战 :用 Appium 抓取手机 app 微信朋友圈的数据
From:https://blog.csdn.net/Fan_shui/article/details/81413595 本编教程从 appium 的环境配置开始,到抓取手机 app 微信朋友圈结束. ...
- Python爬虫+夜神模拟器+Fiddler抓取手机APP数据接口 -- 图文教程(霸霸看了都说好)
Fiddler的抓包原理 Fiddler是强大的抓包工具,它的原理是以web代理服务器的形式进行工作的,使用的代理地址是:127.0.0.1,端口默认为8888,我们也可以通过设置进行修改. 代理就是 ...
- python3 爬虫实战案例 (抓取淘宝信息)(淘宝加了搜索必须登录的验证,此方法所到的结果都是0)
需求:对比足球,篮球,乒乓球,羽毛球,网球,相关物品的销售量保存到excle中 和抓取淘宝关键字相关信息的销售量,这和之前抓取csdn网站浏览量取不同,抓取csdn浏览量主要是通过bs4Tag标签,而 ...
- python手机软件-Python爬虫:抓取手机APP的数据
分享一篇文章,原文来自:j_hao104的个人页面. 摘要 大多数APP里面返回的是json格式数据,或者一堆加密过的数据 .这里以超级课程表APP为例,抓取超级课程表里用户发的话题. 1.抓取APP ...
- Python爬虫:抓取手机APP的数据
点击上方"程序员大咖",选择"置顶公众号" 关键时刻,第一时间送达! 抓取APP数据包 得到超级课程表登录的地址:http://120.55.151.61/V2 ...
- 十六、爬虫实战,多线程抓取毛豆新车的数据
前言: 对于爬虫还有一点小知识 fake_useragent的使用 fake_useragent第三方库,来实现随机请求头的设置: 安装 -> pip3 install fake-userage ...
- Charles抓取手机APP接口数据使用方法
一.Charles环境安装 需要具备jdk1.8 Jdk下载官网:https://www.oracle.com/technetwork/java/javase/downloads/index.html ...
- 十七、爬虫实战,多线程抓取大搜网新车的数据
上次爬取毛豆新车的数据 十六.爬虫实战,多线程抓取毛豆新车的数据 这次爬取大搜车卖车 爬虫实战 对于之前学的知识,作一个整合,爬取大搜车卖车信息 目标:爬取大搜车卖车信息,并写入mongodb数据库 ...
- Python爬虫实战六之抓取爱问知识人问题并保存至数据库
大家好,本次为大家带来的是抓取爱问知识人的问题并将问题和答案保存到数据库的方法,涉及的内容包括: Urllib的用法及异常处理 Beautiful Soup的简单应用 MySQLdb的基础用法 正则表 ...
最新文章
- (2006, 'MySQL server has gone away') 错误解决 - dba007的空间 - 51CTO技术博客
- WF单元测试系列3:测试Activity的行为
- php7的redis和yaf的扩展安装
- 测试用例的常用设计方法
- 深入理解yield from语法
- 3.列表(一个打了激素的数组)
- 软件项目管理0713:三级等保的重要性
- 2-1 gradle安装
- CN Erlounge IV 讲师名单公布及Call For Topic
- java 里面write,java 中 System.out.println()和System.out.write()的区别
- 【将图像字符画】【第二玩】图像字符化
- Django实现简单的用户添加、删除、修改等功能
- 2019,国产手机生死存亡的一年
- python图片内容识别_ubuntu 安装 pytesseract 模块进行图片内容识别
- Tensor Flow V2:将Tensor Flow H5模型文件转换为tflite
- 在OpenFOAM中获取网格详细信息
- NAT和代理服务器的调研
- 100亿+数据量,每天50W+查询,携程酒店数据智能平台实践
- C++STL(下)——关联式容器(Associative Containers)与算法
- 2018年清华大学民商法学考研经验分享
热门文章
- 数据恢复软件-你删除过“小片”,它都能给你找出来....
- [opencv] 伪彩色和彩虹图
- springboot配置启动后自动打开浏览器访问项目
- node+express使用multiparty实现文件上传
- 快排递归和非递归(java)
- Android单元测试网络请求问题
- 【深度解析】Java中的乐观锁、悲观锁
- uniapp中使用canvas 画海报总结
- 洛谷P1848 [USACO12OPEN]书架Bookshelf
- vue中vue.runtime.esm.js?2b0e:619 [Vue warn]: data functions should return an object:报错原因