打算上架一批NFT到os上
但os只能一次上传一张图片
如果上传个成百上千张岂不是累si了?!!
所以打算用Python进行批量上传。
1. 导出 mm
在 chrome 上安裝 mm
把浏览器內mm特定的扩展程序导出、封裝成 .crx 文件,
同时会有一个用于认证的 .pem 秘钥文件
前往 chrome://extensions/
将右上角的「开发人员模式」打开,
就能看到每个扩展功能的 ID,先把你要备份导出的扩展程序ID记住。
打开文件管理器,在上方路径输入:
C:\Users\{UserName}\AppData\Local\Google\Chrome\User Data\Default\Extensions
注意将UserName替换成自己的用户名,
这样就能看到所有已安装的扩展程序文件夹
找到对应上面ID的文件夹,点击进入,复制路径
找到mm=>详情=>打包扩展程序
输入 mm extension 的本地路径,将会生成一个 .crx 文件
粘贴上面找到的路径点击打包扩展程序
成功后会生成.crx文件 跟 .pem 秘钥
如果提示“指定扩展程序的私有密钥已存在。请重复使用该密钥,或者先删除它。”,请选择已存在的私有密钥,或者删除它,会重新生成该秘钥;
如果提示“清单文件缺失或不可读取”,或是类似其他无法导出的问题,通常路径选择错误,
切记进入到根目录下,例如:C:\Users\xxx\AppData\Local\Google\Chrome\User Data\Default\Extensions\nkbihfbeogaeaoehlefnkodbefgpgknn\10.16.1_0
2. 连接 Mm
没安装python去官网下载安装一下即可
Download Python | Python.org
selenium官网下载 chromedriver
根据自己的谷歌浏览器版本下载chromedriver,或者相近的版本
接着安装相应的包准备开始执行
pip install selenium
pip install bs4
编写如下 python 代码供之后把 mm 导入webdriver
把PHASE、PASSWORD换成你自己的
为了文章排版有换行的地方请自行调整一下!
mm_connector.py:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
import time
# 生成的扩展文件路径(替换成自己的)
EXTENSION_PATH = r"C:\Users\XXX\AppData\Local\Google\Chrome\User Data\Default\Extensions\nkbihfbeogaeaoehlefnkodbefgpgknn\10.14.3_0.crx"
opt = webdriver.ChromeOptions()
opt.add_extension(EXTENSION_PATH)
# 一定程度上避免被服务器认定是爬虫
opt.add_experimental_option("excludeSwitches", ["enable-automation"])
opt.add_experimental_option('useAutomationExtension', False)
opt.add_argument("--disable-blink-features=AutomationControlled")
service_chromedriver = Service("./chromedriver.exe") # chromedriver.exe要跟mm_connector.py在同一目录下
driver = webdriver.Chrome(service=service_chromedriver, options=opt)
def meta_mask_navigate():
SECRET_RECOVERY_PHRASE = 'mm钱包助记词'
NEW_PASSWORD = 'mm钱包登录密码'
driver.switch_to.window(driver.window_handles[0])
time.sleep(3)
# 导入助记词创建钱包
driver.find_element(By.CLASS_NAME, "first-time-flow__button").click()
#driver.find_element(By.XPATH, "//button [text()='开始使用']").click()
time.sleep(1)
driver.find_element(By.XPATH, "//button [text()='导入钱包']").click()
time.sleep(1)
driver.find_element(By.XPATH, "//button [text()='我同意']").click()
time.sleep(1)
inputs = driver.find_elements(By.XPATH, '//input')
''' 一下代码新版的钱包不能用了
inputs[0].send_keys(SECRET_RECOVERY_PHRASE)
inputs[1].send_keys(NEW_PASSWORD)
inputs[2].send_keys(NEW_PASSWORD)
'''
# 以前是一次粘贴所有的助记词,新版钱包是依次粘贴24个助记词,根据实际情况自行调整
key_arr = SECRET_RECOVERY_PHRASE.split(" ")
j = 0
for i in range(24):
if i % 2 == 0:
inputs[i].send_keys(key_arr[j])
j += 1
inputs[24].send_keys(NEW_PASSWORD)
inputs[25].send_keys(NEW_PASSWORD)
checkbox_list = driver.find_elements(By.ID, "create-new-vault__terms-checkbox")
checkbox_list[0].click()
time.sleep(1)
driver.find_element(By.XPATH, "//button [text()='导入']").click()
time.sleep(5)
driver.find_element(By.XPATH, "//button [text()='全部完成']").click()
time.sleep(2)
driver.find_element(By.CLASS_NAME, "popover-header__button").click()
time.sleep(2)
def get_driver():
return driver
3. os端
- 创建一个os账户(国内需要科学上网)
- 通过 mm 钱包连接到 os
- 創建NFT集合 链接
操作os上传
将collection网址、图片路径自己的
sleep time 根据、电脑状态调成自己的,求稳不求快,否则可能会被服务器发现进而被限制!
os_uploader.py:
import time
import random
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import mm_connector
import os
from pathlib import Path
# 连接mm钱包
mm_connector.meta_mask_navigate()
# 获取driver
driver = mm_connector.get_driver()
# 随机sleep, 避免被发现,可以根据实际情况调整
time_to_sleep = random.randint(5,10)
time.sleep(time_to_sleep)
# 打开事先创建好的 collection 链接 (是第三个窗口,mm是第二个窗口)
driver.execute_script('window.open("https://os.io/collection/sunset-cloudss/assets/create","_blank")')
time.sleep(time_to_sleep)
print(driver.window_handles)
# window handle是惰性的,不会自动切换,如果打开了一个新的窗口,想在新窗口上获取某一元素,需要先手动切换
# driver.window_handles可以获取所有窗口句柄
# 切换到第三个句柄(collection)
driver.switch_to.window(driver.window_handles[2])
print(driver.title)
time.sleep(time_to_sleep)
# 选择mm钱包登录
driver.find_element(By.XPATH, "//span [text()='MetaMask']").click()
time.sleep(time_to_sleep)
print(driver.window_handles)
driver.switch_to.window(driver.window_handles[3])
time.sleep(time_to_sleep)
driver.find_element(By.CLASS_NAME, "btn-primary").click()
time.sleep(time_to_sleep)
print(driver.window_handles)
driver.find_element(By.CLASS_NAME, "btn-primary").click()
time.sleep(time_to_sleep)
print(driver.window_handles)
driver.switch_to.window(driver.window_handles[3])
time.sleep(time_to_sleep)
print(driver.window_handles)
driver.find_element(By.CLASS_NAME, "btn-primary").click()
time.sleep(time_to_sleep)
driver.switch_to.window(driver.window_handles[2])
# 需要上传的图片路径
folder_dir = "D:\\xxx\\IMG"
# 描述
description = "May there be enough clouds in your life to make a beautiful sunset!"
if not os.path.exists(folder_dir + '/uploaded'):
os.mkdir(folder_dir + '/uploaded')
time.sleep(time_to_sleep)
for images in os.listdir(folder_dir):
# check if the image ends with png
if (images.endswith(".jpg")):
print(images)
inputs = driver.find_elements(By.XPATH, '//input')
inputs[1].send_keys(folder_dir + '/' + images)
inputs[2].send_keys(images.replace(".jpg", ""))
textareas = driver.find_elements(By.XPATH, '//textarea')
textareas[0].send_keys(description)
time.sleep(1)
driver.find_element(By.XPATH, "//button [text()='Create']").click()
time.sleep(25)
# driver.find_element(By.XPATH, "//i [text()='close']").click()
# driver.find_element(By.CLASS_NAME, "material-icons").click()
# 解决: Element is not clickable at point,Other element would receive the click
# 用执行js的方式来提交,果然可以避免这个问题
button = WebDriverWait(driver, 15).until(
EC.visibility_of_element_located((By.XPATH, '/html/body/div[6]/div/div/div/div[2]/button/i'))
)
driver.execute_script("arguments[0].click();", button)
Path(folder_dir + '/' + images).rename(folder_dir + '/uploaded/' + images)
time.sleep(10)
driver.execute_script('window.open("https://osxxx.io/collection/sunset-cloudss/assets/create","_self")')
执行os_uploader.py会将目标文件夹下的图片一一上传
已上传的图片会被移入uploaded文件夹
所以程序中断后直接重新执行 os_uploader.py 即可
用不了多久就传好海量NFT了!