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

楼主: funky1221 (funky)   2020-05-17 16:02:42
因为有一堆旅游的照片及影片,想把它上传到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('[email protected]
.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('
作者: boboye (me)   2020-05-17 17:38:00
很有趣的应用,谢谢
作者: nini200 (200妮妮)   2020-05-17 18:17:00
有趣 谢谢分享
作者: st1009 (前端攻城师)   2020-05-17 20:02:00
推推
作者: TuCH (谬客)   2020-05-17 22:34:00
可以学会放上github之类的
作者: cuteSquirrel (松鼠)   2020-05-17 22:50:00
作者: sating00 (sating00)   2020-05-18 00:25:00
有rclone呢...不过有Notify也不错
作者: kenduest (小州)   2020-05-18 01:57:00
Google photo api 文件有说上传的图片都是原始格式不会压缩处理,所以若是你要不占用空间得自己 resize 成为1600万画素,一般用 Pillow 处理一下就可以。
作者: TakiDog (多奇狗)   2020-05-18 09:25:00
...用Python做按键脚本的概念,Selenium登入Google可以用profile有实作给个推,可以试着改用API吧
作者: penut85420 (PenutGGorz)   2020-05-18 10:06:00
推推
作者: andrew66666 (加藤桑关门弟子)   2020-05-18 10:14:00
推~
作者: kenduest (小州)   2020-05-19 00:11:00
影片部分,只要你影片没有超过 1080p 记得不压缩的所以你用 api or web 处理最后影片结果都是一样若你是拍 4k 可能就是不一样情况
作者: TWhtml (冷冷的冰)   2020-05-19 00:31:00
作者: unmolk (UJ)   2020-05-19 11:08:00
推 其实可以推上github 不用这么辛苦打程式码在这XD
作者: powerkshs (气质斯文读书人)   2020-05-19 17:51:00
酷喔

Links booklink

Contact Us: admin [ a t ] ucptt.com