华为云照片的爬虫程序更新(python3.6)

一、背景:

每年终都有一个习惯,就是整理资料进行归档,结果发现手机照片全备份在华为云里,在官网上找了一圈,没找到官方的pc工具用来同步照片。

于是找出上次写的程序,看看能不能爬到数据,然而……果然不好用。因为华为在登录上又增加了一些验证机制,譬如:账号保护

抓了一下报文,发现逻辑变复杂了很多,部分逻辑还封装在js里。

算了,懒得琢磨了,直接用selenium吧。

二、实现思路:

1、用Python + selenium +浏览器 ,人工登录,保存cookie及签名信息。

2、再调用requests加第一步保存的cookie和前面,直接向后台发post请求,获取数据。

思路确定,开干。

三、开发环境:

1、python3.6,在最近的一个项目中由于多次遇到中文问题,实在是烦不胜烦,所以就把开发工具升级到了py3,确实方便多了。

说到py2升到py3,虽然还是有些写法调整,有些包在py3下不支持,但总体来说,迁移很平稳,写法问题,百度一下基本就可以解决。

我用的Anaconda的python包。

3.6.3 |Anaconda custom (64-bit)| (default, Oct 15 2017, 03:27:45) [MSC v.1900 64 bit (AMD64)]
Python Type "help", "copyright", "credits" or "license" for more information.

2、selenium 3.9.0,用conda现安装的。

conda install selenium 

3、浏览器,试用了firefox,edge,chrome,phantomjs,分别版本如下:

firefox: 58.0.2 (64 位)
edge: Microsoft Edge 41.16299.248.0 ,Microsoft Edge 41.16299.248.0
chrome: 版本 63.0.3239.132(正式版本) (32 位)
phantomjs: 2.1.1 

另外,操作系统:Microsoft Windows [版本 10.0.16299.248]

4、浏览器驱动:

firefox驱动,https://github.com/mozilla/geckodriver/releases/,支持 Firefox 55及以上版本。

edge驱动,https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/#downloads,最新版本 Release 16299,Version: 5.16299,支持 Edge version supported: 16.16299 。注意edge驱动只有在edge浏览器未启动的情况下才能正常运行,否则会报错。

chrome驱动,https://sites.google.com/a/chromium.org/chromedriver/downloads,这里需要注意的是:最新版本是2.35(不是2.9),2.35才支持chrome 61-63版本。

phantomjs,http://phantomjs.org/download.html,phantomjs可以理解成没有界面的浏览器,所以驱动跟浏览器是一体的。

驱动版本一定要选对,否则会有奇奇怪怪的问题。

四、实现代码

huaweiphoto_sele.py,如下:

#-*-coding=utf-8-*-
#Create by : Joshua zou
#Create Date : 2018.2.28

from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.common.proxy import ProxyType
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from PIL import Image
import json,re,os,time,requests,socket

#下载函数
from  huaweiphoto_py3_new import HuaWei

class hwSele:
    SeleBrowser=None
    TimeOUT=30
    Headers=None
    Username=‘*****‘
    Passwd=‘****‘
    DriverType="Edge".lower()
    def __init__(self,ip=None,port=None,SeleDriver="Edge",SeleHeader=None):
        print (u‘proxy %s %s...‘ %(ip,port))
        if not SeleHeader :
            self.Headers = "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:56.0) Gecko/20100101 Firefox/56.0"
        else:
            self.Headers = SeleHeader

        if SeleDriver:
            self.DriverType= SeleDriver.lower()

        #加代理的目的是为了更便于抓报文。
        if self.DriverType==‘chrome‘ :
            chromeOptions = webdriver.ChromeOptions()
            if ip:
                chromeOptions.add_argument(‘--proxy-server=http://%s:%s‘ %(ip,port))
                self.SeleBrowser = webdriver.Chrome(chrome_options=chromeOptions)
            else:
                self.SeleBrowser = webdriver.Chrome()
        #DriverType=‘Edge‘
        elif self.DriverType==‘phantomjs‘:
            #设置userAgent
            dcap = dict(DesiredCapabilities.PHANTOMJS)
            dcap["phantomjs.page.settings.userAgent"] = (self.Headers)
            self.SeleBrowser = webdriver.PhantomJS(executable_path=r‘D:\python\toupiao\phantomjs\bin\phantomjs.exe‘,desired_capabilities=dcap)
            if ip:
                proxy=webdriver.Proxy()
                proxy.proxy_type=ProxyType.MANUAL
                proxy.http_proxy=‘%s:%s‘ %(ip,port)
                proxy.add_to_capabilities(webdriver.DesiredCapabilities.PHANTOMJS)
            else:
                self.SeleBrowser.start_session(webdriver.DesiredCapabilities.PHANTOMJS)
        elif self.DriverType==‘edge‘:
            self.KillSeleProc() #edge,默认先kill掉已启动的浏览器。
            self.SeleBrowser = webdriver.Edge()
        elif self.DriverType==‘firefox‘:
            webdriver.DesiredCapabilities.FIREFOX[‘firefox.page.settings.userAgent‘] = self.Headers
            profile = webdriver.FirefoxProfile()
            if ip:
                profile.set_preference(‘network.proxy.type‘, 1)  # 默认值0,就是直接连接;1就是手工配置代理。
                profile.set_preference(‘network.proxy.http‘, ip)
                profile.set_preference(‘network.proxy.http_port‘, port)
                profile.set_preference(‘network.proxy.ssl‘, ip)
                profile.set_preference(‘network.proxy.ssl_port‘, port)
                profile.update_preferences()
                self.SeleBrowser = webdriver.Firefox(profile)
            else:
                self.SeleBrowser = webdriver.Firefox()
        socket.setdefaulttimeout(self.TimeOUT)
        # 设置10秒页面超时返回,类似于requests.get()的timeout选项,driver.get()没有timeout选项
        # 以前遇到过driver.get(url)一直不返回,但也不报错的问题,这时程序会卡住,设置超时选项能解决这个问题。
        self.SeleBrowser.set_page_load_timeout(self.TimeOUT)
        # 设置10秒脚本超时时间
        self.SeleBrowser.set_script_timeout(self.TimeOUT)
        # 隐式等待30秒,可以自己调节
        self.SeleBrowser.implicitly_wait(self.TimeOUT)

    def KillSeleProc(self):
        if self.DriverType==‘edge‘:
            command = ‘taskkill /F /IM MicrosoftWebDriver.exe & taskkill /F /IM MicrosoftEdge.exe‘
            #比如这里关闭edge进程
        elif self.DriverType==‘chrome‘:
            command = ‘taskkill /F /IM chromedriver.exe & taskkill /F /IM chrome.exe‘
        elif self.DriverType==‘firefox‘:
            command = ‘taskkill /F /IM geckodriver.exe & taskkill /F /IM firefox.exe‘
        elif self.DriverType=="phantomjs":
            command = ‘taskkill /F /IM phantomjs.exe ‘
        if command: os.system(command)

    def QuitSele(self,e,mess=None,iRet= -1):
        print (mess,e)
        if self.SeleBrowser:
            self.SeleBrowser.save_screenshot(‘error.png‘)
            self.SeleBrowser.close()
        self.KillSeleProc()
        return iRet

    def LoginHW(self):
        ‘‘‘
        try:
            element = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "loadedButton")))
        finally:
            print(driver.find_element_by_id("content").text)
            driver.close()

        #等待页面加载完毕1,显示等待
        try:
            auth_img = WebDriverWait(self.SeleBrowser, 5).until(EC.presence_of_element_located((By.ID, "randomCodeImg")))
        except Exception as e:
            print (u‘加载验证码超时...‘,e)
            SeleBrowser.save_screenshot(r‘d:\python\toupiao\error.jpg‘)
            self.SeleBrowser.close()
            return -1 

        #等待页面加载完毕2,隐式等待
        dr=WebDriverWait(self.SeleBrowser,20,0.5)
        dr.until(lambda the_driver:the_driver.find_element_by_xpath("//img[@id=‘randomCodeImg‘]").is_displayed())
        ‘‘‘
        try:
            self.SeleBrowser.get(‘http://cloud.huawei.com‘)
        except Exception as e:
            return self.QuitSele(e,"打开主页出错!")

        try:
            #等待页面加载完毕
            dr=WebDriverWait(self.SeleBrowser,self.TimeOUT,0.5)
            dr.until(lambda the_driver:the_driver.find_element_by_id("randomCodeImg").is_displayed())
        except Exception as e:
            return self.QuitSele(e,"加载验证码超时!")

        elem_user = self.SeleBrowser.find_element_by_id("login_userName")
        elem_user.clear()
        elem_user.send_keys(self.Username)

        elem_pwd =  self.SeleBrowser.find_element_by_id("login_password")
        elem_pwd.clear()
        elem_pwd.send_keys(self.Passwd)        

        auth_img = self.SeleBrowser.find_element_by_id("randomCodeImg")
        if not auth_img.is_displayed() :
            if not auth_img.is_displayed():
                return self.QuitSele(e,"验证码未正常显示!")

        if self.DriverType==‘firefox‘:
            #firefox驱动支持直接 元素另存图片
            auth_img.screenshot("captcha.png")
            im = Image.open(‘captcha.png‘)
        else:
            #chrome ,edge 都不支持,phantomjs存的还是整个窗口
            self.SeleBrowser.save_screenshot(‘captcha.png‘)
            im = Image.open(‘captcha.png‘)
            x= eval(auth_img.get_attribute("x"))
            y= eval(auth_img.get_attribute("y"))
            width= eval(auth_img.get_attribute("width"))
            height= eval(auth_img.get_attribute("height"))
            im = im.crop((x, y, x+width, y+height))
        #这里采用最原始、最准确的方法:显示图片,人工识别^_^,智能输入验证码。
        #当然也可以调用三方的图像识别api进行识别,譬如pytesseract或者鹅厂的图像识别api,不复杂,但懒得写了。
        im.show()
        authCode= input(u‘请输入验证码:‘)

        # 先获取焦点,再赋值,再点击登录
        ‘‘‘
        js= ‘$("#randomCode").attr("value","%s");$("#randomCode").trigger("onchange");‘ %authCode
        self.SeleBrowser.execute_script(js)

        js= ‘$("#btnLogin").trigger("click");‘
        self.SeleBrowser.execute_script(js)
        ‘‘‘
        randomCode = self.SeleBrowser.find_element_by_id("randomCode")
        randomCode.clear()
        randomCode.send_keys(authCode)

        #休息五秒,等待完成后台预验证交互
        time.sleep(5)

        btnLogin = self.SeleBrowser.find_element_by_id("btnLogin")
        btnLogin.click()

        #账号保护有时候会提示
        ‘‘‘
        <div class="global_dialog_confirm_main" style="display: block; margin-top: -163.5px;">
        <div class="global_dialog_confirm_title">
        <h3 class="ellipsis" title="帐号保护">帐号保护</h3>    </div>
        <div class="global_dialog_confirm_content" style="padding-bottom: 0px;"><div>
        <div id="authenDialog"><p class="inptips2">您已开启帐号保护,请输入验证码以完成登录。</p>
        <div class="margin10-EMUI5"><div id="accountDiv" class="fixAccountDrt ddrop-EMU5">
        ‘‘‘
        try :
            #loginConfirm = self.SeleBrowser.find_element_by_class_name("global_dialog_confirm_main")
            loginConfirm =WebDriverWait(self.SeleBrowser, 5, 0.5).until(EC.presence_of_element_located((By.CLASS_NAME, ‘global_dialog_confirm_main‘) ))
            #需要验证,这块懒得实现了,休眠60秒,手动操作吧。
            if loginConfirm.is_displayed():
                time.sleep(self.TimeOUT*2)
        except:
            #不需要验证,直接下一步
            pass

        #等待页面加载完毕
        ‘‘‘
        <span class="index-span" data-bind="lang.common.album">图库</span>
        ‘‘‘
        try :
            #loginConfirm = self.SeleBrowser.find_element_by_class_name("global_dialog_confirm_main")
            success =WebDriverWait(self.SeleBrowser, 20, 0.5).until(EC.presence_of_element_located((By.XPATH, ‘//span[@data-bind="lang.common.album"]‘) ))
        except Exception as e:
            #登录失败
            return self.QuitSele(e,"登录失败!",iRet=-999)

        #判断登录结果
        if not success.is_displayed(): return self.QuitSele(None,"登录失败!",iRet=-999)

        #再次判断,增加一次意外处理
        source_code =self.SeleBrowser.page_source
        if ‘联系人‘ not in source_code or ‘图库‘ not in source_code :
            return self.QuitSele(None,"登录失败!",iRet = -9999 )

        cookie = [item["name"] + "=" + item["value"] for item in self.SeleBrowser.get_cookies()]
        cookiestr = ‘;‘.join(item for item in cookie)
        #保存CSRFToken
        pattern = re.compile(‘CSRFToken = "(.*?)"‘,re.S)
        content = re.search(pattern,source_code)
        if content :
            CSRFToken = content.group(1)
        else :
            print (‘获取CSRFToken出错!‘)
        self.Headers={
            ‘User-Agent‘: ‘%s‘ %self.Headers,
            ‘CSRFToken‘: ‘%s‘ %CSRFToken,
            ‘Cookie‘: ‘%s‘ %cookiestr
        }
        return 1 

if __name__ == ‘__main__‘:
    photohw= HuaWei()
    count =0
    while (count <100):
        count += 1
        selehw= hwSele(SeleDriver=‘edge‘)
        iRet = selehw.LoginHW()
        if iRet !=1:
            print( ‘登录华为失败!!!\n\n‘)
            continue
        photohw.loginHeaders = selehw.Headers
        page = photohw.getAlbumList()
        if page==‘‘ :
            print( ‘获取到相册列表失败!!!\n\n‘)
            break
        #保存相册列表
        iRet = photohw.getFileList(page,‘albumList‘,‘albumId‘)
        if iRet <=0 :
            print(‘保存相册出错,重新登录‘)
            continue
        #保存公共相册列表
        iRet = photohw.getFileList(page,‘ownShareList‘,‘shareId‘)
        if iRet ==0 :
            print(‘运行结束,可以用迅雷打开相册文件进行批量下载到本地!!!\n\n‘)
            #运行结束
            selehw.QuitSele(None)
            break
        else:
            continue  

huwweiphoto_py3.py如下:

# -*- coding=utf-8 -*-
# Create by : Joshua zou
# Create date : 2018.2.28
__author__=‘joshua zou‘

import json
import requests
from requests.adapters import HTTPAdapter
import html

class HuaWei:
    #华为云服务登录
    def __init__(self):
        self.getalbumsUrl= ‘https://www.hicloud.com/album/getCloudAlbums.action‘
        self.getalbumfileUrl = ‘https://www.hicloud.com/album/getCloudFiles.action‘
        self.loginHeaders = { }
        self.SReq=requests.session()
        self.SReq.mount(‘http://‘, HTTPAdapter(max_retries=3))
        self.SReq.mount(‘https://‘, HTTPAdapter(max_retries=3))
        self.OnceMaxFile=100 #单次最大获取文件数量
        self.FileNum=0
        self.AlbumList={}

    #保存相册照片地址到文件 ,不同相册保存到不同的文件
    def saveFileList2Txt(self,filename,hjsondata,flag):
        if len(hjsondata)<= 0 : return -1
        hjson2 = {}
        try:
            hjson2 = json.loads(hjsondata)
        except:
            print(‘获取相册明细出错\n‘)
            return -1

        lfilename = filename+u".txt"
        if flag == 0 : #新建文件
            print( u‘创建相册文件‘+lfilename+"\n")
            #新建文件,代表新的相册重新开始计数
            self.FileNum = 0
            f = open(lfilename, ‘w‘)
        else: #追加文件
            f = open(lfilename, ‘a‘)
        i = 0
        if hjson2.get("fileList"):
            for each in hjson2["fileList"]:
                fileurl= html.unescape(hjson2["fileList"][i]["fileUrl"])
                f.write(fileurl+"\n")
                #每一千行分页
                self.FileNum += 1
                if self.FileNum%1000 ==0 :f.write(‘\n\n\n\n\n\n--------------------page %s ------------------\n\n\n\n\n\n‘ %(int(self.FileNum/1000)))
                i += 1
        f.close()
        return i

    #循环读取相册文件
    def getFileList(self,hjsondata,parentkey,childkey):
        #step 3 getCoverFiles.action,循环取相册文件列表,单次最多取100条记录。
        #每次count都是最大数量49,不管实际数量是否够,每次currentnum递增,直到返回空列表。
        #albumIds[]=default-album-2&ownerId=220086000029851117&height=300&width=300&count=49&currentNum=0&thumbType=imgcropa&fileType=0
        #albumIds[]=default-album-1&ownerId=220086000029851117&height=300&width=300&count=49&currentNum=49&thumbType=imgcropa&fileType=0
        #albumIds[]=default-album-1&ownerId=220086000029851117&height=300&width=300&count=49&currentNum=98&thumbType=imgcropa&fileType=0
        #albumIds[]=default-album-2&ownerId=220086000029851117&height=300&width=300&count=49&currentNum=101&thumbType=imgcropa&fileType=0
        #最后一次返回 空列表
        #{"albumSortFlag":true,"code":0,"info":"success!","fileList":[]}
        #第一次取文件时,例如文件总数量只有2个,count也是放最大值49。
        #albumIds[]=default-album-102-220086000029851117&ownerId=220086000029851117&height=300&width=300&count=49&currentNum=0&thumbType=imgcropa&fileType=0
        #[{u‘photoNum‘: 2518, u‘albumName‘: u‘default-album-1‘, u‘iversion‘: -1, u‘albumId‘: u‘default-album-1‘, u‘flversion‘: -1, u‘createTime‘: 1448065264550L, u‘size‘: 0},
        #{u‘photoNum‘: 100, u‘albumName‘: u‘default-album-2‘, u‘iversion‘: -1, u‘albumId‘: u‘default-album-2‘, u‘flversion‘: -1, u‘createTime‘: 1453090781646L, u‘size‘: 0}]
        try:
            hjson = json.loads(hjsondata)
        except Exception:
            print (‘加载json出错!‘)
            return -1

        #字典获取出错
        if not hjson.get(parentkey):
            print (‘加载json根节点[%s]出错!‘ %parentkey)
            return -1

        #初始化全局 albumlist
        if not self.AlbumList :
            self.AlbumList=hjson

        for idx,album in enumerate(self.AlbumList[parentkey]):
            if ‘currentNum‘ not in self.AlbumList[parentkey][idx].keys():
                self.AlbumList[parentkey][idx][‘currentNum‘]=0

        #循环保存相册
        for each in hjson[parentkey]:
            #该相册已经进入记录
            paraAlbum={}
            paraAlbum[‘albumIds[]‘] = each[childkey]
            paraAlbum[‘ownerId‘] = hjson[‘ownerId‘]
            paraAlbum[‘height‘] = ‘300‘
            paraAlbum[‘width‘] = ‘300‘
            paraAlbum[‘count‘] = self.OnceMaxFile
            paraAlbum[‘thumbType‘] = ‘imgcropa‘
            paraAlbum[‘fileType‘] = ‘0‘
            itotal= each[‘photoNum‘]

            #取当前节点的当前记录
            for idx,album in enumerate(self.AlbumList[parentkey]):
                if each[childkey]==album[childkey]:
                    icurrentnum = self.AlbumList[parentkey][idx][‘currentNum‘]
                    break

            #保存相册中所有文件
            while icurrentnum<itotal:
                paraAlbum[‘currentNum‘] = icurrentnum
                response=self.SReq.post(self.getalbumfileUrl,headers=self.loginHeaders,data=paraAlbum,verify=False)
                page = response.text
                #保存下载地址到文本文件中,但不下载文件
                iret  = self.saveFileList2Txt(each[childkey],page,icurrentnum)
                if iret >0 :
                    self.AlbumList[parentkey][idx][‘currentNum‘]  += iret
                    icurrentnum = self.AlbumList[parentkey][idx][‘currentNum‘]
                else:
                    #出错!!!
                    return -1
        return 1

    #step 1 getCloudAlbums,取相册列表
    def getAlbumList(self):
        response=self.SReq.post(self.getalbumsUrl,headers=self.loginHeaders,verify=False)
        page=response.text
        ‘‘‘#返回报文
        {"ownerId":"220086000029851117","code":0,
        "albumList":[{"albumId":"default-album-1","albumName":"default-album-1","createTime":1448065264550,"photoNum":2521,"flversion":-1,"iversion":-1,"size":0},
                     {"albumId":"default-album-2","albumName":"default-album-2","createTime":1453090781646,"photoNum":101,"flversion":-1,"iversion":-1,"size":0}],
        "ownShareList":[{"ownerId":"220086000029851117","resource":"album","shareId":"default-album-102-220086000029851117","shareName":"微信","photoNum":2,"flversion":-1,"iversion":-1,"createTime":1448070407055,"source":"HUAWEI MT7-TL00","size":0,"ownerAcc":"****","receiverList":[]}],
        "recShareList":[]}‘
        ‘‘‘
        if len(page)<=0 :
            print( u‘取相册列表出错,无返回报文!!!\n\n‘)
        return page

以上,-- End --

原文地址:https://www.cnblogs.com/zhongtang/p/8478307.html

时间: 2024-10-10 03:45:47

华为云照片的爬虫程序更新(python3.6)的相关文章

从教务网爬虫程序到腾讯云上的运行

从教务网爬虫程序到腾讯云上的运行 主要内容有以下几方面: pip3以及相关python包的安装 mysql数据库的连接以及相关操作 腾讯云服务器的设置与连接,文件传输等操作 pip3以及相关python包的安装 在使用python3时,需要安装对应的pip版本,即pip3.ubuntu系统下的安装方式如下: $ sudo apt-get install python3-pip 安装完成后就可以使用pip3来安装相应的python包,如requests包的安装方式如下: $ sudo pip3 i

Python3网络爬虫(十一):爬虫黑科技之让你的爬虫程序更像人类用户的行为(代理IP池等)

原文链接: Jack-Cui,http://blog.csdn.net/c406495762 运行平台: Windows Python版本: Python3.x IDE: Sublime text3 1 前言 近期,有些朋友问我一些关于如何应对反爬虫的问题.由于好多朋友都在问,因此决定写一篇此类的博客.把我知道的一些方法,分享给大家.博主属于小菜级别,玩爬虫也完全是处于兴趣爱好,如有不足之处,还望指正. 在互联网上进行自动数据采集(抓取)这件事和互联网存在的时间差不多一样长.今天大众好像更倾向于

Cloud Native Weekly | KubeCon首登中国,华为云亮相KubeCon

1.KubeCon首登中国,Kubernetes将如何再演进? 11月14日,由CNCF发起的云原生领域全球最大的峰会之一KubeCon+CloudNativeCon首次登陆中国,中国已经成为云原生领域一股强大力量,并且还在不断成长.在一些大公司,容器已经取得了显著的效果.京东从 OpenStack 迁移至 Kubernetes,资源利用率提高 30%:华为迁移至云原生环境后,运营成本削减 20-30%:雅虎日本已经利用Kubernetes自动进行生产部署:中国移动也开始使用容器代替虚拟机在平台

Cloud Native Weekly | 华为云抢先发布Redis5.0,红帽宣布收购混合云提供商

1--华为云抢先发布Redis5.02--DigitalOcean K8s服务正式上线 3--红帽宣布收购混合云提供商 NooBaa 4--微软发布多项 Azure Kubernetes 服务更新 1 华为云抢先发布Redis5.0 12月17日,华为云在DCS2.0的基础上,快人一步,抢先推出了新的Redis 5.0产品,这是一个崭新的突破.目前国内在缓存领域的发展普遍停留在Redis4.0阶段,华为云率先发布了Redis5.0,全面展现了华为云在业界缓存领域持续创新的实力.华为云分布式缓存R

华为云提供针对Nuget包管理器的缓存加速服务

在Visual Studio 2013.2015.2017中,使用的是Nuget包管理器对第三方组件进行管理升级的.而且 Nuget 是我们使用.NET Core的一项基础设施,.NET的软件包管理器NuGet.org是一项面向全球用户搭建的服务,不论用户身在何处,NuGet.org都应该有能力提供高性能的服务.2017 年微软针对中国访问Nuget服务的访问慢的问题进行了优化,把Blob存储备份到中国本地,并使用本地CDN服务商来处理软件包下载请求,具体参考 https://blog.nuge

拍照党福利驾到 华为云微认证教你实现图片压缩和水印添加

在手机拍照成为日常的今天,用照片记录生活已成为人们的一种习惯.拍照容易处理难,面对手机相册中大量的照片,你是否也苦恼过?删,舍不得:上传,会不会被盗图?能否发出足够个性的图片称霸朋友圈?不用担心,华为云微认证结合函数工作流服务,教你轻松实现图片压缩和水印添加,让您体验函数工作流带来的高资源利用率和高处理效率,让即便是无照不活的拍照党也再无后顾之忧. 云服务助力图片存储及管理一般而言,我们压缩图片有四种方法:使用图片压缩软件.网页在线图片压缩.自设图片压缩代码.使用云服务批量压缩.水印添加一般也有

华为云-公有云架构

华为公有云架构华为公有云的主要服务如弹性云服务器(ECS).弹性伸缩服务(AS).云硬盘(EVS).云硬盘备份(VBS).对象存储服务(OBS) .虚拟私有云(VPC).弹性负载均衡(ELB).Anti-DDOS流量清洗.云数据库(RDS).IAM统一身份认证.云监控服务(CES).EI.API等云服务产品. 一. 公有云服务架构 1.公有云全堆栈解决方案使能数字化转型 2.华为公有云架构 3.高可用的资源架构模型 二. 公有云服务的主要服务产品 1.华为云标准产品体系 2.计算服务:弹性云服务

学习猿地 python教程 django教程6 华为云部署

# 上线华为云服务器部署(弹性云服务器ECS) >环境配置: > ubuntu 18.04 > Python 3.6.8(python3.7亦可) > nginx version: nginx/1.14.0 (Ubuntu) ## 1. 购买华为云服务器 文档 https://support.huaweicloud.com/ecs/index.html ## 2. 上传到华为云服务器,安装依赖环境,启动项目测试 #### 1.导出当前项目的依赖环境 `pip freeze >

安全狗入驻华为云应用超市 共建云安全服务体系

近日,厦门服云信息科技有限公司(以下简称:厦门服云)旗下安全狗产品及"安全狗加固系统环境"正式进驻华为云应用超市. 随着国内云计算的发展,各大云计算产商都在加强应用生态建设.华为云属于国内较早建立应用生态的厂商,在安全品类中,厦门服云是华为云重要的合作伙伴,此次厦门服云与华为云服务达成合作协议,"安全狗加固系统环境"进驻华为云应用超市,目的就是为了给平台用户提供完整的安全系统环境搭建和系统加固服务,解决用户在云服务器系统搭建过程中产生的安全问题,全面提升安全性能,也