Automatically and massively upload and sell your non-fungible tokens on OpenSea using Python Selenium.
A Selenium Python bot to automatically and bulky upload and sell your NFTs on OpenSea
(all metadata integrated - Ethereum and Polygon supported) - reCAPTCHA solver included.
Please read the README file before using this tool, opening a problem or a discussion, or contacting me.
⇒ Open an issue? Provide an excerpt from your metadata file, your operating system and detail your error.
⇒ Make sure you have the latest modules, browser and bot installed.
⇒ Read the pinned and opened issues, see the example metadata files.
- What does this bot do?
- Changelog.
- Prerequisites.
- Instructions.
- Data files structure.
- Configuration of the sale part of the NFTs.
- Known issues and important things to know.
This script allows you to upload and sell as many NFTs as you want to OpenSea, all automatically and quickly. All metadata are integrated, and the Ethereum and Polygon Blockchains are supported.
You can decide whether you want to upload or sell your NFTs, or both. If you upload your NFTs and sell them later, a CSV file is created with the URL of the NFT as well as its Blockchain and supply number.
➜ If you sell any NFT with this bot, you can consider sharing some of your earnings: 😉
0xDD135d5be0a23f6daAAE7D2d0580828c9e09402E (Ethereum).
➜ Or you can buy me a NFT from my collection Crypto Parrot if this bot was useful to you.
- Version 1.6.4:
- The bot did not go to the sale page after the sequence of a failure and a success. #225.
- Version 1.6.3:
- Added support for Coinbase Wallet (many thanks to MathieuAndrade!).
- Version 1.6.2:
- Version 1.6.1:
- Updated the
requirements.txt
file, conflicts and problems seem to be corrected. - Removed unnecessary files from the
yolov5/
directory. - Fixed the problem of connection to OpenSea.
- Improved reCAPTCHA verification when solved.
- Updated the
- Version 1.6.0:
- Version 1.5.12:
- Version 1.5.11:
- Version 1.5.10:
- Minor fixes concerning the
sale()
method of the OpenSea class. - Fixed exception iteration error.
- Minor fixes concerning the
- Version 1.5.9:
- The
close()
method of the Webdriver class has been fixed. It creates an exception when listing NFTs. As a result, it does not try to list them a second time. #144, #145, #149. - During the download, when the webdriver starts, sometimes an error occurs and creates an exception. It was supposed to close the webdriver but it caused the bot to crash.
- The download of webdriver requires a manual entry of the path after a number of failures.
- The
- Version 1.5.8:
- Errors related to incorrectly formatted files are now supported. An error is displayed but the bot does not stop abruptly. #90.
- False listing errors are reduced, the robot checks a second time if the NFT is correctly listed.
- Version 1.5.7:
- With each failed upload or sale, the bot retries a second time before saving the NFT data in an autogenerated file.
- The duration has been fixed for GeckoDriver (Mozilla Firefox). #121.
- Version 1.5.6:
- The
dict_to_list()
method has been optimized and shortened. - Minor fixes.
- The
- Version 1.5.5:
- Fixed the
metamask_contract()
method. It was not signing the contract when completing the listing for the Ethereum Blockchain. - Minor fixes.
- Fixed the
- Version 1.5.4:
- The HTTPConnectionPool error in Selenium is fixed, it was caused by defining the driver inside a loop. Now the bot will print an error and restart to launch the bot. #112.
➜ For more informations: Reddit - Ralphc360's comment. - You can now sell your NFTs on the Ethereum Blockchain for free.
- The HTTPConnectionPool error in Selenium is fixed, it was caused by defining the driver inside a loop. Now the bot will print an error and restart to launch the bot. #112.
- Version 1.5.3:
- Version 1.5.2:
- Version 1.5.1:
- Fixed the problem of the worker version 1.5.0. The bot now continues to upload and does not restart the upload from the beginning. #107.
- Version 1.5.0:
- The reCAPTCHAs can now be bypassed. The bot restarts for each upload - it's a bit slow but it works. #98, #102.
Thanks to Kanishka-Chandra and elwanm. - The bot restarts after 3 failed connections to the wallet or to OpenSea.
- The reCAPTCHAs can now be bypassed. The bot restarts for each upload - it's a bit slow but it works. #98, #102.
- Version 1.4.9:
- Minor fixes.
- Developers can now add new wallets if they wish.
- ChromeDriver is automatically downloaded - no need to do it manually (
pip install -r requirements.txt
required). - The reCAPTCHAs solver is not integrated/configured.
- Version 1.4.8:
Added a new feature that allows to upload more than 50 items in a collection. Requires to be activated (asked at launch).(Method used: https://www.youtube.com/watch?v=8wpmjh8xrXo). Update: This method is useless because OpenSea went back on its words. The limit has been removed.- Minor fix.
- Version 1.4.7:
- The default language of ChromeDriver is now English to ensure maximum compatibility. The date did not work in some countries because of the different formats that OpenSea offers. #67.
- Minor fix (Colorama module).
- Version 1.4.6:
- The duration has been corrected. OpenSea does not allow to change the year when the next year is more than 6 months away. So it was impossible to enter the month without it being replaced by December (12 - maximum number because the year was entered instead); Note: maximum duration is 6 months. #55.
- The connection to OpenSea has certainly been corrected. (need feedback about this - I don't have any problems on my side). #53, #58, #61.
- Version 1.4.5:
- Minor fix for Linux users. The
clear_text(self)
method inserts an "A" when it tries to clear the inputs before sending the data. #39.
- Minor fix for Linux users. The
- Version 1.4.4:
- Connection to OpenSea with MetaMask corrected. Download of the extension was requested. #53.
- Connection to OpenSea with MetaMask improved.
- Version 1.4.3:
- File preview is now added. #48.
- Version 1.4.2:
- Listing of NFT on the Ethereum Blockchain is fully supported. Be sure to make a deposit and have more than 0.05 ETH on your wallet.
- Version 1.4.1:
- Version 1.4:
- You can now decide whether you want to upload or sell your NFTs, or both. #3, #22.
- Signing the MetaMask contract works every time. It can take 30 seconds to be signed when connecting to OpenSea. #5, #17.
- After uploading the NFT, the bot would crash when it tried to sell it (the URL was not correct). Now it doesn't. #17.
- MacOS and Linux support improved.
- Calendar method improved.
- Version 1.3:
- Version 1.2:
- Possibility to set a price for each NFT added.
➜ 1+ supplies and Polygon blockchain support added. - Supply input issue fixed.
- Calendar method improved.
- Possibility to set a price for each NFT added.
- Version 1.2-alpha:
- Possibility to set a price for each NFT added.
- Version 1.1:
- XLSX support added.
- PC-wide data file browse support.
- Properties, Stats and Levels issues fixed. #1.
- Version 1.0:
- Inital commit.
- A graphics card (GPU) with CUDA (Compute Unified Device Architecture).
-
Search for your GPU on GPUZoo and check if CUDA is compatible (Cores / Texture -> CUDA).
-
Open a command prompt and type this command to check your CUDA version (it must be 11.6 or higher):
nvidia-smi
-
If your CUDA version is earlier than 11.3, update it at the NVIDIA website.
-
Then type this command to install PyTorch (install Python and pip first: Instructions):
pip install torch==1.11.0+cu113 torchvision==0.12.0+cu113 torchaudio===0.11.0+cu113 -f https://download.pytorch.org/whl/cu113/torch_stable.html
Previous versions of PyTorch with older CUDA version: https://pytorch.org/get-started/previous-versions/
-
- If your graphic card doesn't have CUDA:
-
Type this command to install PyTorch (install Python and pip first: Instructions):
pip install torch torchvision torchaudio
-
- A computer with enough power.
-
-
Download the repository or clone it by typing this command in your command prompt:
git clone https://github.com/maximedrn/opensea-automatic-bulk-upload-and-sale.git
-
It requires Python 3.9.7+ (3.10 can be unstable) - developped with Python 3.9.9.
-
Install pip to be able to have needed Python modules.
-
-
-
Extract the repository folder from the ZIP file, you should have a folder named
opensea-automatic-bulk-upload-and-sale-master
. -
Open a command prompt in the repository folder and type one of these commands (may require
sudo
on MacOS and Linux and administrator privileges for Windows):-
pip install -r requirements.txt
-
pip3 install -r requirements.txt
-
python -m pip install -r requirements.txt
-
python3 -m pip install -r requirements.txt
-
py -m pip install -r requirements.txt
-
-
Download and install Google Chrome and/or Mozilla Firefox.
-
Create your NFTs data file containing all details of each NFT. It can be a JSON, CSV or XLSX file. You can save it in the
data/
folder.
What structure should the files have?
-
-
-
Open a command prompt in the
opensea-automatic-bulk-upload-and-sale-master/
folder path. -
Type one of these commands to run the bot:
-
python main.py
-
python3 main.py
-
-
If you do not want to add details to the values not required, leave:
-
a blank cell for XLSX files (Excel):
File Path NFT Name Description C:/Users/Admin/Desktop/NFT/nft_0001.png NFT #1 -
a white space with two semicolons for CSV files:
file_path;; nft_name;; description;; C:/Users/Admin/Desktop/NFT/nft_0001.png;; NFT #1;; ;;
-
an empty string for JSON files:
"file_path": "C:/Users/Admin/Desktop/NFT/nft_0001.png", "nft_name": "NFT #1", "description": "",
Required values *
(Mandatory value in certain specified cases)
-
Details Data Types Literal examples JSON examples CSV examples XLSX examples File Path * (The preview is only for files that are not images) String or List "file_path": "C:/Users/Admin/Desktop/NFT/nft_0001.png",
"file_path": ["C:/Users/Admin/Desktop/NFT/nft_0001.mp4", "C:/Users/Admin/Desktop/NFT/nft_0001-preview.png"],C:/Users/Admin/Desktop/NFT/nft_0001.png;;
["C:/Users/Admin/Desktop/NFT/nft_0001.mp4", "C:/Users/Admin/Desktop/NFT/nft_0001-preview.png"];;C:/Users/Admin/Desktop/NFT/nft_0001.png
["C:/Users/Admin/Desktop/NFT/nft_0001.mp4", "C:/Users/Admin/Desktop/NFT/nft_0001-preview.png"];;NFT Name * String "nft_name": "NFT #1", NFT #1;; NFT #1 External Link String "external_link": "https://github.com/maximedrn/opensea-automatic-bulk-upload-and-sale",
"external_link": "",https://github.com/maximedrn/opensea-automatic-bulk-upload-and-sale;; https://github.com/maximedrn/opensea-automatic-bulk-upload-and-sale Description String "description": "This is my first NFT.",
"description": "",This is my first NFT.;; This is my first NFT. Collection String "collection": "My NFTs",
"collection": "",My NFTs;; My NFTs. Properties List[[String, String], ...]
List[String, String]["type", "name"]
[["type", "name"], ["type", "name"]]"properties": [{ "type": "Dog", "name": "Male" }, { "type": "Cat", "name": "Female" }],
"properties": [{ "type": "Dog", "name": "Male" }],
"properties": "",[["Dog", "Male"], ["Cat", "Female"]];;
[["Dog", "Male"]];;
["Dog", "Male"];;[["Dog", "Male"], ["Cat", "Female"]]
[["Dog", "Male"]]
["Dog", "Male"]Levels List[[String, Integer, Integer], ...]
List[String, Integer, Integer]["name", value_from, value_to]
[["name", value_from, value_to], ["name", value_from, value_to]]"levels": [{ "name": "Speed", "from": 2, "to": 5 }, { "name": "Width", "from": 1, "to": 10 }],
"levels": [{ "name": "Speed", "from": 2, "to": 5 }],
"levels": "",[["Speed", 2, 5], ["Width", 1, 10]];;
[["Speed", 2, 5]];;
["Speed", 2, 5];;[["Speed", 2, 5], ["Width", 1, 10]]
[["Speed", 2, 5]]
["Speed", 2, 5]Stats List[[String, Integer, Integer], ...]
List[String, Integer, Integer]["name", value_from, value_to]
[["name", value_from, value_to], ["name", value_from, value_to]]"stats": [{ "name": "Strenght", "from": 10, "to": 100 }, { "name": "Age", "from": 1, "to": 99 }],
"stats": [{ "name": "Strenght", "from": 10, "to": 100 }],
"stats": "",[["Strenght", 10, 100], ["Age", 1, 99]];;
[["Strenght", 10, 100]];;
["Strenght", 10, 100];;[["Strenght", 10, 100], ["Age", 1, 99]]
[["Strenght", 10, 100]]
["Strenght", 10, 100]Unlockable Content List[Boolean, String]
List[Boolean]
Boolean[True, "unlockable_content"]
[False]
False"unlockable_content": [true, "Thank you for purchasing my NFT!"],
"unlockable_content": [false],
"unlockable_content": false,
"unlockable_content": "",[True, "Thank you for purchasing my NFT!"];;
[False];;
False;;[True, "Thank you for purchasing my NFT!"]
[False]
FalseExplicit And Sensitive Content Boolean "explicit_and_sensitive_content": true,
"explicit_and_sensitive_content": false,
"explicit_and_sensitive_content": "",True;;
False;;True
FalseSupply Integer "supply": 1,
"supply" : "",1;; 1 Blockchain String "blockchain": "Polygon",
"blockchain" : "",Polygon;; Polygon Sale Type (only for Ethereum Blockchain and 1 supply) String "sale_type": "Timed Auction",
"sale_type": "",Timed Auction;; Timed Auction Price * Float or Integer "price": 5,
"price": 0.25,5;;
0.25;;5
0.25Method (only for "Timed Auction") List[String, Float] ["method", price]
["method, ""]"method": ["Sell with declining price", 0.002],
"method": ["Sell to highest bidder", 0.05],
"method": ["Sell to highest bidder", ""],
"method": "",["Sell with declining price", 0.002];;
["Sell to highest bidder", 0.05];;
["Sell to highest bidder", ""];;["Sell with declining price", 0.002]
["Sell to highest bidder", 0.05]
["Sell to highest bidder", ""]Duration ("DD-MM-YYYY HH:MM") List[String, String]
List[String]
String["from_date", "to_date"]
["days/weeks/months"]
"days/weeks/months""duration": ["01-01-2022 14:00", "01-04-2022 15:00"],
"duration": ["1 week"],
"duration": "1 week",
"duration": "",["01-01-2022 14:00", "01-04-2022 15:00"];;
["1 week"];;
1 week;;["01-01-2022 14:00", "01-04-2022 15:00"]
["1 week"]
1 weekSpecific Buyer List[Boolean, String]
[Boolean]
Boolean[True, "wallet"]
[False]
False"specific_buyer": [true, "0xDD135d5be0a23f6daAAE7D2d0580828c9e09402E"],
"specific_buyer": [false],
"specific_buyer": false,
"specific_buyer": "",[True, "0xDD135d5be0a23f6daAAE7D2d0580828c9e09402E"];;
[False];;
False;;[True, "0xDD135d5be0a23f6daAAE7D2d0580828c9e09402E"]
[False]
FalseQuantity * (only for 1+ supplies) Integer "quantity": 4
"quantity": ""4 4 And it gives you something like this: JSON, CSV, XLSX (must be downloaded to view it).
-
Details Data Types Literal examples JSON examples CSV examples XLSX examples File Path * (The preview is only for files that are not images) String or List "file_path": "C:/Users/Admin/Desktop/NFT/nft_0001.png",
"file_path": ["C:/Users/Admin/Desktop/NFT/nft_0001.mp4", "C:/Users/Admin/Desktop/NFT/nft_0001-preview.png"],C:/Users/Admin/Desktop/NFT/nft_0001.png;;
["C:/Users/Admin/Desktop/NFT/nft_0001.mp4", "C:/Users/Admin/Desktop/NFT/nft_0001-preview.png"];;C:/Users/Admin/Desktop/NFT/nft_0001.png
["C:/Users/Admin/Desktop/NFT/nft_0001.mp4", "C:/Users/Admin/Desktop/NFT/nft_0001-preview.png"];;NFT Name * String "nft_name": "NFT #1", NFT #1;; NFT #1 External Link String "external_link": "https://github.com/maximedrn/opensea-automatic-bulk-upload-and-sale",
"external_link": "",https://github.com/maximedrn/opensea-automatic-bulk-upload-and-sale;; https://github.com/maximedrn/opensea-automatic-bulk-upload-and-sale Description String "description": "This is my first NFT.",
"description": "",This is my first NFT.;; This is my first NFT. Collection String "collection": "My NFTs",
"collection": "",My NFTs;; My NFTs. Properties List[[String, String], ...]
List[String, String]["type", "name"]
[["type", "name"], ["type", "name"]]"properties": [{ "type": "Dog", "name": "Male" }, { "type": "Cat", "name": "Female" }],
"properties": [{ "type": "Dog", "name": "Male" }],
"properties": "",[["Dog", "Male"], ["Cat", "Female"]];;
[["Dog", "Male"]];;
["Dog", "Male"];;[["Dog", "Male"], ["Cat", "Female"]]
[["Dog", "Male"]]
["Dog", "Male"]Levels List[[String, Integer, Integer], ...]
List[String, Integer, Integer]["name", value_from, value_to]
[["name", value_from, value_to], ["name", value_from, value_to]]"levels": [{ "name": "Speed", "from": 2, "to": 5 }, { "name": "Width", "from": 1, "to": 10 }],
"levels": [{ "name": "Speed", "from": 2, "to": 5 }],
"levels": "",[["Speed", 2, 5], ["Width", 1, 10]];;
[["Speed", 2, 5]];;
["Speed", 2, 5];;[["Speed", 2, 5], ["Width", 1, 10]]
[["Speed", 2, 5]]
["Speed", 2, 5]Stats List[[String, Integer, Integer], ...]
List[String, Integer, Integer]["name", value_from, value_to]
[["name", value_from, value_to], ["name", value_from, value_to]]"stats": [{ "name": "Strenght", "from": 10, "to": 100 }, { "name": "Age", "from": 1, "to": 99 }],
"stats": [{ "name": "Strenght", "from": 10, "to": 100 }],
"stats": "",[["Strenght", 10, 100], ["Age", 1, 99]];;
[["Strenght", 10, 100]];;
["Strenght", 10, 100];;[["Strenght", 10, 100], ["Age", 1, 99]]
[["Strenght", 10, 100]]
["Strenght", 10, 100]Unlockable Content List[Boolean, String]
List[Boolean]
Boolean[True, "unlockable_content"]
[False]
False"unlockable_content": [true, "Thank you for purchasing my NFT!"],
"unlockable_content": [false],
"unlockable_content": false,
"unlockable_content": "",[True, "Thank you for purchasing my NFT!"];;
[False];;
False;;[True, "Thank you for purchasing my NFT!"]
[False]
FalseExplicit And Sensitive Content Boolean "explicit_and_sensitive_content": true,
"explicit_and_sensitive_content": false,
"explicit_and_sensitive_content": "",True;;
False;;True
FalseSupply * Integer "supply": 1, 1;; 1 Blockchain * String "blockchain": "Polygon" Polygon Polygon And it gives you something like this: JSON, CSV, XLSX (must be downloaded to view it).
-
If you have already uploaded your NFTs with this bot, a file has been generatcontaining the URL, the Blockchain and the supply number of each NFT. You have to complete it with sale values.
Details Data Types Literal examples JSON examples CSV examples XLSX examples NFT URL * String "nft_url": "https://opensea.io/assets/matic/0x2953399124f0cbb46d2cbacd8a89cf0599974963/99995353970554757559721471534129028266698199001274859511402524949800648966145", https://opensea.io/assets/matic/0x2953399124f0cbb46d2cbacd8a89cf0599974963/99995353970554757559721471534129028266698199001274859511402524949800648966145;; https://opensea.io/assets/matic/0x2953399124f0cbb46d2cbacd8a89cf0599974963/99995353970554757559721471534129028266698199001274859511402524949800648966145 Supply * Integer "supply": 1, 1;; 1 Blockchain * String "blockchain": "Polygon", Polygon;; Polygon Sale Type (only for Ethereum Blockchain and 1 supply) String "sale_type": "Timed Auction",
"sale_type": "",Timed Auction;; Timed Auction Price * Float or Integer "price": 5,
"price: 0.25,5;;
0.25;;5
0.25Method (only for "Timed Auction") List[String, Float] ["method", price]
["method, ""]"method": ["Sell with declining price", 0.002],
"method": ["Sell to highest bidder", 0.05],
"method": ["Sell to highest bidder", ""],
"method": "",["Sell with declining price", 0.002];;
["Sell to highest bidder", 0.05];;
["Sell to highest bidder", ""];;["Sell with declining price", 0.002]
["Sell to highest bidder", 0.05]
["Sell to highest bidder", ""]Duration ("DD-MM-YYYY HH:MM") List[String, String]
List[String]
String["from_date", "to_date"]
["days/weeks/months"]
"days/weeks/months""duration": ["01-01-2022 14:00", "01-04-2022 15:00"],
"duration": ["1 week"],
"duration": "1 week",
"duration": "",["01-01-2022 14:00", "01-04-2022 15:00"];;
["1 week"];;
1 week;;["01-01-2022 14:00", "01-04-2022 15:00"]
["1 week"]
1 weekSpecific Buyer List[Boolean, String]
[Boolean]
Boolean[True, "wallet"]
[False]
False"specific_buyer": [true, "0xDD135d5be0a23f6daAAE7D2d0580828c9e09402E"]
"specific_buyer": [false]
"specific_buyer": false,
specific_buyer": "",[True, "0xDD135d5be0a23f6daAAE7D2d0580828c9e09402E"];;
[False];;
False;;[True, "0xDD135d5be0a23f6daAAE7D2d0580828c9e09402E"]
[False]
FalseQuantity * (only for 1+ supplies) Integer "quantity": 4
"quantity": ""4 4 And it gives you something like this: JSON, CSV, XLSX (must be downloaded to view it).
When you want to sell your NFTs, Opensea requires various details according to their Blockchain or supply number.
Note: The maximum duration of sale should be at most 6 months. It must be entered in the form of start date - end date.
Ethereum | Polygon | ||||||||||||||||||||
Supply number equal to 1 | Supply number higher than 1 | Supply number equal to 1 | Supply number higher than 1 | ||||||||||||||||||
Fixed Price | Timed Auction | ||||||||||||||||||||
Sell to highest bidder | Sell with declining price | ||||||||||||||||||||
Price (ETH) | Duration (from a date to an other date or 1 day, 3 days, 1 week, 1 month) | Reserve for a specific buyer | Price (ETH) | Duration (from a date to an other date or 1 day, 3 days, 1 week) | (Optional) Reserved Price (WETH) greater than 1 WETH and greater than the Starting Price. | Reserve for a specific buyer | Starting Price (ETH) | Duration (from a date to an other date or 1 day, 3 days, 1 week) | Ending Price (ETH) less than the Starting Price. | Reserve for a specific buyer | Quantity | Price (ETH) | Duration (from a date to an other date or 1 day, 3 days, 1 week, 1 month) | Reserve for a specific buyer | Price (ETH) | Duration (from a date to an other date or 1 day, 3 days, 1 week, 1 month) | Reserve for a specific buyer | Quantity | Price (ETH) | Duration (from a date to an other date or 1 day, 3 days, 1 week, 1 month) | Reserve for a specific buyer |
-
Make sure to deposit Ethereum (ETH/WETH) or Polygon (MATIC) on your wallet before proceeding to the sale. Otherwise the bot will cancel the sale. Opensea needs an Ethereum wallet with more than 0.05 ETH or a Polygon wallet with a deposit of any amount. For Ethereum, you have to make a first listing manually before using this bot.
-
The file path should not contain a unique "\". It can be a "/" or a "\\", as you can see for the JSON file (it applies to all file formats):
// You can use this format for your path: "file_path": "C:/Users/Admin/Desktop/MyNFTs/nft_0001.png", // or this one: "file_path": "C:\\Users\\Admin\\Desktop\\MyNFTs\\nft_0001.png", // but not this one (you can see that "\" is highlighted in red): "file_path": "C:\Users\Admin\Desktop\MyNFTs\nft_0001.png",
-
The bot may crash at the beginning when loading the MetaMask extension (a Selenium module issue), An error like the one below should appear:
selenium.common.exceptions.WebDriverException: Message: unknown error: failed to wait for extension background page to load: chrome-extension://nkbihfbeogaeaoehlefnkodbefpgknn/background.html from timeout: Timed out receiving message from renderer: 10.000
-
When lauching the webdriver, Selenium can raise an exception:
driver = webdriver.Chrome(service=Service( # DeprecationWarning using TypeError: WebDriver.init() got an unexpected keyword argument 'service'
You must update your Selenium version to 4.1.0 or higher by typing in the command prompt:
pip install selenium --upgrade
You can now verify that a more recent version of Selenium is installed by typing:
pip show selenium