[心得] 上傳照片或影片到 Google Photo

看板Python作者 (funky)時間5年前 (2020/05/17 16:02), 5年前編輯推噓11(1109)
留言20則, 13人參與, 5年前最新討論串1/3 (看更多)
因為有一堆旅遊的照片及影片,想把它上傳到google photo 一開始利用 google photo API 上傳,研究了好久,而且網上 相關資訊不多,google 官網的資訊又跳來跳去,有看沒有懂, 好不容易寫完且上傳成功,但發現它會占用你google的空間, 後來還是放棄,朝selenium方式上傳,但又遇到一個難題, google 會擋直接用 webdriver 登入,後來在 stackoverflow 看到有人分享可利用第3方網站取得google 登入授權的方式 來登入google,最終終於可以無限上傳我的照片及影片! 我的程式設定成每次上傳 8 hrs, 8小時到會自動關閉, 上傳會產生一個列表 xml,然後會紀錄哪一個檔案上傳 成功,下次上傳會繼續從未上傳成功的檔案繼續,我都是 利用半夜自動上傳,不然會占據頻寬,全部上傳完成會利用 LineNotify 通知你,希望這個能幫助 正在學習 python 的初學者! 我的code 如果有錯誤的地方 也不吝指正,我不是本科出身,也是python的初學者,我的 學習都是google 來的,所以也分享給大家! # -*- coding: utf-8 -*- from xml.dom.minidom import Document import xml.etree.ElementTree as ET from selenium import webdriver from selenium.common.exceptions import NoSuchElementException import logging import os import sys import win32gui import win32con import time import requests from datetime import datetime, timedelta import fnmatch import re mytime = datetime.now() + timedelta(hours=8) # 上傳的時間設定 basepath = os.path.dirname(__file__) # 本檔的路徑 filelog = os.path.join(basepath, 'list.log') # 上傳的紀錄檔 xml = os.path.join(basepath, 'filelist.xml') # 上傳的檔案列表 uploadpath = 'xxxxx' # 你要上傳的照片影片 資料夾 # 開啟紀錄 LogTemp.log def EnableLogging(): logging.basicConfig(level=logging.INFO, format='%(asctime)s %(name)-1s %(levelname)-1s %(message)s', datefmt='%m-%d %H:%M', handlers=[logging.FileHandler(filelog), ]) def LoginGoogle(): url = 'https://stackoverflow.com/users/signup?ssrc=head&returnurl=%2fusers%2fstory%2 fcurrent%27' option = webdriver.ChromeOptions() option.add_argument('disable-infobars') driver = webdriver.Chrome(chrome_options=option) driver.get(url) time.sleep(5) driver.find_element_by_xpath('//*[@id="openid-buttons"]/button[1]').click() driver.find_element_by_xpath('//input[@type="email"]').send_keys('xxxxxx@gmail .com') driver.find_element_by_xpath('//*[@id="identifierNext"]').click() time.sleep(3) driver.find_element_by_xpath('//input[@type="password"]').send_keys('xxxxxxxx') driver.find_element_by_xpath('//*[@id="passwordNext"]').click() time.sleep(2) # go to album url = 'your album' driver.get(url) time.sleep(5) return driver def UploadFile(driver, file): # Click upload pictures elems = driver.find_element_by_xpath('//*[@id="yDmH0d"]/c-wiz/div[4]/c-wiz/c-wiz[1]/di v[2]/span/div/div[2]/button') elems.click() time.sleep(3) # Click upload from local computer elems = driver.find_element_by_xpath('//*[@id="yDmH0d"]/div[2]/div/div[2]/span/div/div [1]/span/div[3]/div[1]/div/div[1]/button') elems.click() time.sleep(3) # win32gui dialog = win32gui.FindWindow('#32770', u'開啟') # 對話方塊 ComboBoxEx32 = win32gui.FindWindowEx(dialog, 0, 'ComboBoxEx32', None) ComboBox = win32gui.FindWindowEx(ComboBoxEx32, 0, 'ComboBox', None) Edit = win32gui.FindWindowEx(ComboBox, 0, 'Edit', None) # 上面三句依次尋 找物件,直到找到輸入框Edit物件的控制代碼 button = win32gui.FindWindowEx(dialog, 0, 'Button', None) # 確定按鈕 Button win32gui.SendMessage(Edit, win32con.WM_SETTEXT, None, file) # 往輸入框輸 入絕對地址 win32gui.SendMessage(dialog, win32con.WM_COMMAND, 1, button) # 按button time.sleep(3) try: while True: elems = driver.find_element_by_xpath('/html/body/div[9]') #判斷是 否上傳完畢 if datetime.now() > mytime: logging.info(file + ' upload failed. Over 8 hours') return False except NoSuchElementException: # upload completed logging.info(file + ' upload completed') return True except: # other error logging.error(file + ' ' + sys.exc_info()[0]) return False def CheckXml(): return os.path.isfile(xml) def ReadXML(driver): tree = ET.parse(xml) root = tree.getroot() nodelist = root.findall('File') for node in nodelist: if node.find('Upload').text == 'false': if UploadFile(driver, node.find('Fullname').text): node.find('Upload').text = 'true' tree.write(xml, encoding="utf-8", xml_declaration=True) else: return False return True def WriteXML(files): doc = Document() base = doc.createElement('UploadFileList') doc.appendChild(base) for fi in files: file = doc.createElement('File') fullname = doc.createElement('Fullname') upload = doc.createElement('Upload') textfullname = doc.createTextNode(fi) isupload = doc.createTextNode('false') fullname.appendChild(textfullname) upload.appendChild(isupload) base.appendChild(file) file.appendChild(fullname) file.appendChild(upload) fname = xml with open(fname, 'w', encoding='utf-8') as f: doc.writexml(f, indent='\t', newl='\n', addindent='\t', encoding='utf-8') f.close def WriteFiles(path): includes = ['*.jpg', '*.mp4'] # for jpg, mp4 files only includes = r'|'.join([fnmatch.translate(x) for x in includes]) list = [] for dirPath, dirNames, fileNames in os.walk(path): list = [os.path.join(dirPath, f) for f in fileNames if re.match(includes, f, re.I)] WriteXML(list) def LineNotifyMessage(msg): token = 'line token' headers = { "Authorization": "Bearer " + token } payload = {'message': msg} r = requests.post("https://notify-api.line.me/api/notify", headers=headers, params = payload) return r.status_code def main(): EnableLogging() logging.info('----------------------------------Getting Started----------------------------------------------------') if not CheckXml(): # 檢查是不是有 xml 檔案列表,若沒有則自動產生 WriteFiles(uploadpath) driver = LoginGoogle() # 登入google if ReadXML(driver): # 讀取檔案列表 xml 開始上傳 LineNotifyMessage('上傳到 Google photo成功') # 全部上傳成功會利用 LineNotify 通知你 driver.quit() if __name__ == '__main__': main() -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 114.44.68.193 (臺灣) ※ 文章網址: https://www.ptt.cc/bbs/Python/M.1589702564.A.C17.html

05/17 17:38, 5年前 , 1F
很有趣的應用,謝謝
05/17 17:38, 1F

05/17 18:17, 5年前 , 2F
有趣 謝謝分享
05/17 18:17, 2F

05/17 20:02, 5年前 , 3F
推推
05/17 20:02, 3F

05/17 22:34, 5年前 , 4F
可以學會放上github之類的
05/17 22:34, 4F

05/17 22:50, 5年前 , 5F
05/17 22:50, 5F

05/18 00:25, 5年前 , 6F
有rclone呢...不過有Notify也不錯
05/18 00:25, 6F

05/18 01:57, 5年前 , 7F
Google photo api 文件有說上傳的圖片都是原始格式不會
05/18 01:57, 7F

05/18 01:57, 5年前 , 8F
壓縮處理,所以若是你要不占用空間得自己 resize 成為
05/18 01:57, 8F

05/18 01:57, 5年前 , 9F
1600萬畫素,一般用 Pillow 處理一下就可以。
05/18 01:57, 9F
其實我最主要的是要上傳影片

05/18 09:25, 5年前 , 10F
...用Python做按鍵腳本的概念,Selenium登入Google可以
05/18 09:25, 10F

05/18 09:25, 5年前 , 11F
用profile
05/18 09:25, 11F
感謝,我試試看

05/18 09:28, 5年前 , 12F
有實作給個推,可以試著改用API吧
05/18 09:28, 12F

05/18 10:06, 5年前 , 13F
推推
05/18 10:06, 13F

05/18 10:14, 5年前 , 14F
推~
05/18 10:14, 14F
※ 編輯: funky1221 (114.44.68.193 臺灣), 05/18/2020 21:58:04

05/19 00:11, 5年前 , 15F
影片部分,只要你影片沒有超過 1080p 記得不壓縮的
05/19 00:11, 15F

05/19 00:11, 5年前 , 16F
所以你用 api or web 處理最後影片結果都是一樣
05/19 00:11, 16F

05/19 00:11, 5年前 , 17F
若你是拍 4k 可能就是不一樣情況
05/19 00:11, 17F

05/19 00:31, 5年前 , 18F
05/19 00:31, 18F

05/19 11:08, 5年前 , 19F
推 其實可以推上github 不用這麼辛苦打程式碼在這XD
05/19 11:08, 19F

05/19 17:51, 5年前 , 20F
酷喔
05/19 17:51, 20F
文章代碼(AID): #1UmE-amN (Python)
文章代碼(AID): #1UmE-amN (Python)