作者funky1221 (funky)
看板Python
标题[心得] 上传照片或影片到 Google Photo
时间Sun May 17 16:02:42 2020
因为有一堆旅游的照片及影片,想把它上传到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://webptt.com/cn.aspx?n=bbs/Python/M.1589702564.A.C17.html
1F:→ boboye: 很有趣的应用,谢谢05/17 17:38
2F:推 nini200: 有趣 谢谢分享 05/17 18:17
3F:推 st1009: 推推05/17 20:02
4F:推 TuCH: 可以学会放上github之类的05/17 22:34
5F:推 cuteSquirrel: 推05/17 22:50
6F:推 sating00: 有rclone呢...不过有Notify也不错05/18 00:25
7F:→ kenduest: Google photo api 文件有说上传的图片都是原始格式不会 05/18 01:57
8F:→ kenduest: 压缩处理,所以若是你要不占用空间得自己 resize 成为05/18 01:57
9F:→ kenduest: 1600万画素,一般用 Pillow 处理一下就可以。05/18 01:57
其实我最主要的是要上传影片
10F:→ TakiDog: ...用Python做按键脚本的概念,Selenium登入Google可以05/18 09:25
11F:→ TakiDog: 用profile05/18 09:25
感谢,我试试看
12F:推 TakiDog: 有实作给个推,可以试着改用API吧05/18 09:28
13F:推 penut85420: 推推05/18 10:06
14F:推 andrew66666: 推~05/18 10:14
※ 编辑: funky1221 (114.44.68.193 台湾), 05/18/2020 21:58:04
15F:→ kenduest: 影片部分,只要你影片没有超过 1080p 记得不压缩的 05/19 00:11
16F:→ kenduest: 所以你用 api or web 处理最後影片结果都是一样 05/19 00:11
17F:→ kenduest: 若你是拍 4k 可能就是不一样情况 05/19 00:11
18F:推 TWhtml: 推 05/19 00:31
19F:推 unmolk: 推 其实可以推上github 不用这麽辛苦打程式码在这XD 05/19 11:08
20F:推 powerkshs: 酷喔 05/19 17:51