python3 爬虫实战 :用 Appium 抓取手机 app 微信朋友圈的数据

 

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 简明教程:https://blog.csdn.net/freeking101/article/details/107881979
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

 

uiautomator2 实战(启动随机播放音乐,并切换到后台):https://www.jianshu.com/p/cd24c6350ce7
uiautomator2 使用教程:https://www.cnblogs.com/Appleli/p/11413229.html
uiautomator2 Github:https://github.com/openatx/uiautomator2
Android自动化测试 - 获取toast提示(Appium+Python+UiAutomator2):
        https://blog.csdn.net/u013059441/article/details/81781245

UIAutomator2 :https://www.jianshu.com/p/e5ed2ddb3f27

 

 

环境搭建

 

为什么选择 Appium

Appium 是一个自动化测试开源工具,支持 iOS 和 Android 平台上的移动原生应用、移动Web应用和混合应用。Appium 是一个跨平台工具,它允许测试人员使用同样的接口、基于不同的平台写自动化测试代码,大大增加了测试套件间代码的复用性。 

  • --- 移动 原生 应用:是指那些用 iOS 或者 android sdk 写的应用; 
  • --- 移动 web 应用:是指那些使用移动浏览器访问的应用,appium 支持 iOS 的 safari 和 android 上的 chrome; 
  • --- 混合 应用:是指原生代码封装在网页视图(原生代码和 web 内容交互)。

 

Appium 的理念

  1. 无需为了自动化,而重新编译或者修改我们的应用;
  2. 不必局限于某种语言或者框架来写和运行测试脚本;
  3. 一个移动自动化的框架不应该在接口上重复造轮子;
  4. 无论精神上,还是名义上,都必须要开源。

 

Appium 的设计

  • Appium 的真正的工作引擎是第三方自动化框架,不需要在本身应用里植入appium 特定或者第三方代码。 
            iOS:苹果的 UI Automator 框架 
            Android 4.2+:Google 的 UI Automator 框架 
            Android 2.3+:Google 的 UI Instrumentation 框架
  • Appium 把这些第三方框架封装成一套 API,即 WebDriver API。
  • Appium 扩充了 WebDriver 的协议,在原有的基础上添加自动化相关的 API 方法。

 

Appium 的相关概念

  1. C/S 架构 
    Appium 的核心是一个 Web 服务器,它提供了一套 REST 的接口。它接收到客户端的连接、监听的命令,接着在移动设备上执行这些命令,然后将执行的结果放在 HTTP 响应中返还给客户端。
  2. Session 
    自动化总是在一个 session 的上下文中运行,客户端初始化一个和服务端交互的 session。客户端发送一个附有 desired capabilities 的 JSON 对象参数的 POST 请求 “/session” 给服务器,服务端就会开始一个自动话的 session,然后返回一个session ID,客户端拿到这个 ID 后就用这个 ID 发送后续的命令。
  3. Desired Capabilities 
    Desired Capabilities 是一些键值对。客户端将这些键值对发给服务端,告诉服务端我们想要启动怎样的自动化session。
  4. Appium server 
    Appium server 是用 nodejs 写的,我们可以源码编译或者从 NPM 直接安装。
  5. Appium 服务端 
    Appium 服务端有很多语言库 Java,Ruby,Python,PHP,JavaScript,C# 等,这些库实现了对 WebDriver 协议的扩展。使用 Appium 的时候,只需使用这些库代替常规的 WebDriver 库就可以了。
  6. Appium.app,Appium.exe 
    Appium 提供了 GUI 封装的 Appium server 下载,它封装了运行 Appium server 的所有依赖元素。而且这个封装包含了一个Inspector 工具,可以让使用者检查应用的界面元素层级。

 

Appium 的环境部署

详细查看 Appium - 安装篇,Appium-Android 开发环境。 
提示:Appium 系统运行要求:Java 7 及以后版本,Android SDK API17 以上版本,Android 虚拟设备或者真实手机设备。

 

开始安装

最开始是按照崔大的环境搭建 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,然后点击  Edit Configurations,可以看到需要两个环境变量,即 前面配置的环境变量。

点击  Start Server ,即可打开 Appium,如下截图:

点击 放大镜 图标,添加 连接字段的信息。

字段说明:

platformName:平台名称
deviceName:设备名称,就是刚才的 adb devices -l 中 mode 后面就是
appPackage:app包名
appActivity:app活动名

有个简单的方法便可以获得 appPackage 和 appActivity:https://blog.csdn.net/mtbaby/article/details/78676477

 

Desired Capabilities 在启动 session 的时候是必须提供的。

Desired Capabilities 本质上是以 key value 字典的方式存放,客户端将这些键值对发给服务端,告诉服务端我们想要怎么测试。它告诉 appium Server这样一些事情:

  • 本次测试是启动浏览器还是启动移动设备。

  • 是启动Andorid还是启动iOS。

  • 启动Android时,app的package是什么。

  • 启动Android时,app的activity是什么。

  • ...

Appium 的 Desired Capabilities 基本配置如下:


DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability("deviceName", "Android Emulator");
capabilities.setCapability("automationName", "Appium");
capabilities.setCapability("platformName", "Android");
capabilities.setCapability("platformVersion", "5.1");
capabilities.setCapability("appPackage", "com.android.calculator2");
capabilities.setCapability("appActivity", ".Calculator");WebDriver driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
  • deviceName:启动哪种设备,是真机还是模拟器?iPhone Simulator,iPad Simulator,iPhone Retina 4-inch,Android Emulator,Galaxy S4...

  • automationName:使用哪种自动化引擎。appium(默认)还是Selendroid。

  • platformName:使用哪种移动平台。iOS, Android, orFirefoxOS。

  • platformVersion:指定平台的系统版本。例如指的Android平台,版本为5.1。

  • appActivity:待测试的app的Activity名字。比如MainActivity、.Settings。注意,原生app的话要在activity前加个"."。

  • appPackage:待测试的app的Java package。比如com.example.android.myApp, com.android.settings。

更多的参数配置 ,参考 这里:https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/caps.md

 

点击 start sessions 后,出现如图所示

我们可以点击左边的登陆(忍不住抱怨下微信,我不就是多登陆了两下,然后微信号被封了一天(*  ̄︿ ̄)),点击登陆后可以看到中间的 App Source 有高亮的代码,就是这个登陆按钮的,可以再看右边的 Selected Element 中有 Tap、Send keys、Clear。
在最左边图中点击登陆后,若最右边下面的 clickable 是 True,则证明可以点击,可以通过点击 Tap 实现点击功能,appium 就介绍到这。 

 

方法 2:

参考:appium连接Android真机,并调试:https://www.cnblogs.com/-ming/p/12085311.html

1. 得到 model 的值

2. 构造连接的 json 字符串( 注意:最后一个字段的后面不要加逗号

{"platformName": "Android","deviceName": "SM_G9750"
}

3. 编辑连接的 json 字符串并保存,然后开始会话。

运行成功后,真机 或者 模拟器上 会安装一个 Appium settings 的 app。

( 当再次连接出现错误时,可以把 Appium settings 卸载,然后再连接模拟器或者真机 )

 

 

 

python 对接 Appium

 

安装 Appium 的 Python 驱动:pip3 install appium-python-client

既然要对接 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 元素定位方法:https://www.cnblogs.com/graybird/p/11312025.html

  • Appium Inspector :Appium 自带的一个功能。( 不推荐使用这个,反应速度太慢。。。 )
  • uiautomator 或者 monitor :Android SDK 自带的工具,在 tools 目录下。( monitor 其实还是调用的 uiautomator )

 

方式 1不推荐使用,反应速度太慢 ):使用 appium 自带定位元素功能,首先看下一些按钮功能说明:

打开 appium 用前面的方式连接微信,定位微信的 "登录" 按钮。( 我使用 appium 选择元素的功能没有定位到登录按钮。。  ) 

其他 app 按钮定位:

但是使用 uiautomator 或者 monitor 却可以定位到,参看 方式 2

 

方式 2( 推荐使用这个,反应速度比较快

uiautomator 或者 monitor :Android SDK 自带的工具。monitor 在 tools 目录下,uiautomator  在 tools\bin 目录下。

下图中,要先点击图中的按钮,才会出现手机上的画面,图中我已经定位到登陆按钮,可以在右边看到属性resource-id,以及clickable=True,确实是可以点击的,为什么要这样确认下呢,因为有的你以为可以点击的元素,也许你定位没有定好,比如说你定位到登陆外更大的一个框,它是不可点击的 

使用 monitor  打开结果截图:

示例代码:

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/f34'))) 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 ByPLATFORM = '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/f34')))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 timePLATFORM = '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/f34')))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 pymongoPLATFORM = '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.weixinself.collection = self.db.weixindef login(self):print('点击登陆按钮——————')login = self.wait.until(EC.presence_of_element_located((By.ID, 'com.tencent.mm:id/f34')))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 都已经诞生了………

如有错误,欢迎指正~

 

 

****************************** 2020.8.9  ******************************

真机上登录微信后,再次点击微信,不需要输入用户名和密码。

使用 appium 直接打开微信 ---> 发现 ---> 朋友圈 ---> 打印昵称和文字内容

示例代码:( 代码中 xpath 是用过 appium 的 Start Recording 自动生成的。。。 )


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 timePLATFORM = 'Android'
deviceName = 'MI_6X'
app_package = 'com.tencent.mm'
app_activity = '.ui.LauncherUI'
driver_server = 'http://127.0.0.1:4723/wd/hub'class Moments(object):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('正在登陆中........')# btn_login = self.wait.until(EC.presence_of_element_located((By.ID, 'com.tencent.mm:id/f34')))# btn_login.click()# btn_change = self.wait.until(EC.presence_of_element_located((By.ID, 'com.tencent.mm:id/d0h')))# btn_change.click()## phone_num = input('输入微信账号:')# edittext_username = self.wait.until(EC.visibility_of_all_elements_located((By.ID, 'com.tencent.mm:id/bem')))# edittext_username[0].send_keys(phone_num)## password = input('输入微信密码:')# edittext = self.wait.until(EC.presence_of_all_elements_located((By.CLASS_NAME, 'android.widget.EditText')))# edittext[1].send_keys(password)## btn = self.wait.until(EC.presence_of_element_located((By.ID, 'com.tencent.mm:id/d0a')))# btn.click()el1 = self.driver.find_element_by_xpath('//android.widget.ImageView[@content-desc="微信"]')el1.click()el1 = self.driver.find_element_by_xpath("//android.widget.FrameLayout[@content-desc=\"当前所在页面,与的聊天\"]/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.view.ViewGroup/android.widget.FrameLayout[1]/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.RelativeLayout/android.widget.LinearLayout/android.widget.RelativeLayout[3]/android.widget.LinearLayout/android.widget.RelativeLayout/android.widget.ImageView[1]")el1.click()time.sleep(2)el2 = self.driver.find_element_by_xpath("//android.widget.FrameLayout[@content-desc=\"当前所在页面,与的聊天\"]/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.view.ViewGroup/android.widget.FrameLayout[1]/android.widget.FrameLayout/android.widget.FrameLayout/com.tencent.mm.ui.mogic.WxViewPager/android.widget.FrameLayout/android.widget.RelativeLayout/android.widget.ListView/android.widget.LinearLayout[1]/android.widget.LinearLayout/android.widget.LinearLayout[1]/android.widget.LinearLayout/android.widget.LinearLayout/android.widget.LinearLayout/android.widget.LinearLayout/android.widget.LinearLayout/android.widget.TextView")el2.click()time.sleep(2)while True:items = self.wait.until(EC.presence_of_all_elements_located((By.XPATH, '//*[@class="android.widget.LinearLayout"]//*[@resource-id="com.tencent.mm:id/fpv"]')))self.driver.swipe(300, 1000, 300, 300)for item in items:try:nickname = item.find_element_by_id('com.tencent.mm:id/e3x').get_attribute('text')print(nickname)content = item.find_element_by_id('com.tencent.mm:id/b_e').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()if __name__ == '__main__':M = Moments()M.main()

 

 

 

 

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

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

相关文章

SharePoint 2010中的内容类型集线器 - 内容类型发布与订阅

原文地址:http://www.chakkaradeep.com/post/SharePoint-2010-Content-Type-Hubs-e28093-Publish-and-Subscribe-to-Content-Types.aspx 注:此博客帖子是基于SharePoint2010技术预览版本。 MOSS 2007 假设您有一个网站集Web Application1 ,在…

如何用“底层逻辑”,看清世界的底牌?

来源:如何用“底层逻辑”,看清世界的底牌? 我的新书《底层逻辑》,终于要和大家见面了。 我常说,只有底层逻辑才有生命力。 因为底层逻辑在面临变化的时候,能够应用到新的变化里面,会产生出新…

python3 爬虫实战:mitmproxy 对接 python 下载抖音小视频

From:https://blog.csdn.net/Fan_shui/article/details/81461253 一、前言 前面我们已经用 appium 爬取了微信朋友圈,今天我们学习下 mitmproxy,mitmproxy 是干什么的呢,它跟 charles 和 fiddler类似,是一个抓包工具&a…

python3 爬虫实战:为爬虫添加 GUI 图像界面 之 tkinter

From:https://blog.csdn.net/Fan_shui/article/details/81611752 一、前言 前面我们写的爬虫只能运行在具有python环境的电脑上,若是把源代码发给别人,很大可能性是运行不了的,所以我们本节的目的是为爬虫创建 GUI 界面&#xff0…

22条API设计的实践

来源:22条API设计的最佳实践 来源:dockone.io/article/2434604 原文:https://betterprogramming.pub/22-best-practices-to-take-your-api-design-skills-to-the-next-level-65569b200b9 曾经因为一个糟糕的API而感到沮丧吗? 在…

linux python 永久添加自己的模块路径

Linux 环境变量配置 : https://blog.csdn.net/freeking101/article/details/81013045 linux python 永久添加自己的模块路径 添加路径: cd /usr/local/python3/lib/python3.6/site-packages vi my.pth 1 . 临时性添加>>>import sys >>>sys.path.a…

边缘计算:智慧城市的下一个浪潮

来源:资本实验室 作者:王进目前,在全球,智慧城市建设处于一个概念到逐步落地的过程,而科技巨头与投资大佬是这一新浪潮重要的参与者。2017年10月,Alphabet旗下城市创新部门Sidewalk Labs宣布,将…

Nature:揭示大脑中的免疫记忆

来源:生物谷摘要:在一项新的研究中,德国研究人员报道身体中的炎症可能影响小鼠大脑中的免疫细胞的“记忆”。在一项新的研究中,德国研究人员报道身体中的炎症可能影响小鼠大脑中的免疫细胞的“记忆”。如果这一发现在人体中得到证…

电竞专业与计算机专业,2021电竞专业的大学排名 电竞专业主要上什么课程

2017年教育部下文增设电竞专业,电子竞技人才培养体系正式形成。为了让广大电竞爱好者,从业者,考生及家长全面客观地了解电竞教育现状,电竞专业高校排行榜应运而生!2021年电竞专业大学排行榜1、中国传媒大学南广学院中国…

计算机主机部件与外设的工作原理,计算机组成原理名词解释和简答

第一章名词解释:1.中央处理器:主要由运算器和控制器组成。控制部件,运算部件,存储部件相互协调,共同完成对指令的执行。2.ALU:对数据进行算术和逻辑运算处理的部件。3.数据通路:由操作元件和存储…

周志华:满足这三大条件,可以考虑不用深度神经网络

来源: AI科技大本营摘要:4 月 15 日举办的京东人工智能创新峰会上,刚刚上任京东人工智能南京分院学术总顾问的周志华教授做了《关于深度学习一点思考》的公开分享。近年来,深度神经网络在语音、图像领域取得突出进展,以…

ibatis常用的集中判断语句

<isPropertyAvailable> 属性是存在<isNotPropertyAvailable> 属性不存在<isNull> 属性值是null<isEmpty> 判断Collection.size<1或String.length()<1<isEqual> 等于<isNotEqual> 不等于<isGreaterThan> 大于<isGreaterEqua…

网络计算机显示10,win10电脑网络显示一个球怎么回事

win10电脑网络显示一个球怎么回事&#xff1f;win10上不了网怎么办&#xff1f;其实这个是网络连接图标&#xff0c;只是因为没网络了就会变成地球图标。那么当出现win10网络变成球状怎么办呢&#xff1f;下面小编教下大家win10电脑网络显示一个球的解决方法。方法一&#xff1…

专家观点 | 李德仁:基于云计算的智慧城市运营脑

来源&#xff1a;智慧城市产业与技术创新战略联盟中国科学院、中国工程院院士李德仁发表了“基于云计算的智慧城市运营脑”的主题报告&#xff0c;深度解读了以公共云服务平台为核心的智慧城市运营脑。首先&#xff0c;李院士就智慧城市及其应用发表了自己的见解。他认为&#…

python3 中的 eval 函数

From&#xff1a;http://blog.csdn.net/zhanh1218/article/details/37562167 Python:eval的妙用和滥用&#xff1a;https://blog.csdn.net/zhanh1218/article/details/37562167 python eval()&#xff1a;http://www.cnblogs.com/dadadechengzi/p/6149930.html Python eval 函…

html超链接去虾线,挑虾线别只会用牙签了,渔民都是这样做的,1秒处理一个,超方便...

现在大家的生活条件已经越来越好&#xff0c;所以说人们在城市的时候也是越来越注意饮食这一方面了&#xff0c;但其实大家在做饭的时候都喜欢买上一些营养丰富的食材&#xff0c;就像是在最近几年海鲜也是让大家都非常喜欢的。海鲜是我们日常生活中都非常喜欢的一个美食&#…

AI将成科学家“高级定制”工具

来源&#xff1a;科技日报 作者&#xff1a;房琳琳化学家有了新的实验助手——人工智能&#xff08;AI&#xff09;。随着深度学习算法的进一步应用&#xff0c;AI计算机程序能帮助药物化合物等小有机分子产生所需的反应序列&#xff0c;制定合成路径。《自然》杂志近日发表了…

华为式创新与海尔式创新——两条道路考验中国制造

来源&#xff1a;企业管理杂志&#xff08;ID&#xff1a;qyglzz&#xff09;作者&#xff1a;吴兴杰&#xff0c;中国管理科学研究院专家咨询委员会副主任、学术委员会委员、研究员以华为为代表的聚合化创新之路非常难走而又不得不走&#xff0c;否则永远只能当二流甚至三流企…

Python 日期 的 加减 等 操作

datetime — Basic date and time types&#xff1a;https://docs.python.org/3.8/library/datetime.html dateutil --- powerful extensions to datetime&#xff1a;https://dateutil.readthedocs.io/en/stable/index.html Python time 和 datetime 的常用转换处理&#xf…