You have a column of image links in a spreadsheet. Product photos, a supplier’s catalog, pictures you picked for a project. You want them all in one folder on your computer.
Page 1 for this search is mostly apps and browser extensions: a Play Store app, a Chrome extension, a paid scraper. You don’t need any of them. Your computer can already download a list of URLs. Google Sheets can write the command for you.
This post shows the technique with any list of URLs, then how my free Free Image Finder sheet does the whole thing for free images from Wikimedia Commons.
TL;DR
- Put the URLs in one column, build one download command per row with a formula, and paste the lot into Terminal or PowerShell.
- Wikimedia and many other sites block downloads with no User-Agent, so always send one with a contact.
- Save the script as plain text; a TextEdit rich text file won’t run.
Who this is for
- Etsy or print-on-demand seller: pull every image you picked into one folder before you start designing.
- E-commerce manager: download a supplier’s product photos from the URL column of their spreadsheet.
- Content writer or blogger: grab every image for a post or a batch of posts at once.
- Researcher or teacher: save a set of pictures for slides or a class pack.
- Video editor: download a batch of B-roll clips without clicking each one.
Before you start
- A Google Sheet with one image URL per row (column A in this post)
- Terminal on a Mac or Linux, or PowerShell on Windows
- A folder to save the files in
Step 1: Get one clean URL per row
Put the URLs in column A, starting at A2. Each one should point at the file itself (ends in .jpg, .png, .webp and so on), not at a web page that shows the picture.
Two quick checks:
- Remove anything after a
?if the site adds tracking.=REGEXREPLACE(A2, "\?.*$", "")does it. - Remove blank rows. Blank lines just make the script print errors.
Step 2: Name each file
If you let the computer name the files, you get whatever the end of the URL is. That’s often fine. If you want your own names, put them in column B, like product-01.jpg.
Single quotes and slashes break file names in a script, so clean them out:
=SUBSTITUTE(SUBSTITUTE(B2, "'", "_"), "/", "_")
Step 3: Build the download command with a formula (Mac and Linux)
In C2, build one curl line per row:
="curl -sSL -A ""MyDownloads/1.0 ([email protected])"" -o '" & SUBSTITUTE(SUBSTITUTE(B2, "'", "_"), "/", "_") & "' '" & A2 & "' && sleep 1"
What each part does:
-
curlis the download tool that ships with every Mac and most Linux machines. -
-sSLhides the progress bar, still shows errors, and follows redirects. -
-Asends a User-Agent: a name for your script and a way to contact you. Wikimedia asks for this, and plenty of other sites refuse requests without one. -
-o 'name'saves the file under your name from column B. -
sleep 1waits a second between files so you don’t hammer the server.
Fill it down. Then put this at the top of a new column to get the whole script in one cell:
=TEXTJOIN(CHAR(10), TRUE, "#!/bin/bash", "mkdir -p downloads && cd downloads", C2:C)
TEXTJOIN with CHAR(10) puts each command on its own line and skips blanks.
Step 4: Run it
- Copy the cell. Open a plain text editor and paste. On a Mac, TextEdit needs Format > Make Plain Text first.
- Save it as
download.shin the folder you want, like your Downloads folder. - Open Terminal, go to that folder (
cd ~/Downloads) and runbash download.sh.
Every file lands in a new downloads folder.
No file names? Use the URL list on its own
Copy column A into a file called urls.txt, one URL per line, then run:
mkdir -p downloads && cd downloads
while read -r url; do curl -sSLO -A "MyDownloads/1.0 ([email protected])" "$url"; sleep 1; done < ../urls.txt
-O keeps the file name from the end of each URL. On Linux, wget -i urls.txt --wait=1 does the same thing. Macs don’t come with wget, so use curl there.
On Windows
Save column A as urls.txt, open PowerShell in that folder, and paste:
New-Item -ItemType Directory -Force downloads | Out-Null
Get-Content urls.txt | ForEach-Object {
$name = [System.Uri]::UnescapeDataString(($_ -split '/')[-1])
Invoke-WebRequest -Uri $_ -OutFile "downloads\$name" -UserAgent "MyDownloads/1.0 ([email protected])"
Start-Sleep -Seconds 1
}
If a file name has characters Windows doesn’t allow, like : or ?, that one fails. Rename it in the list and run it again. Or paste the URL list into any bulk downloader app.
The shortcut: Free Image Finder does all of this for free images
If what you’re downloading is free pictures, I already built this into a sheet. Free Image Finder searches over 100 million free photos, drawings and videos on Wikimedia Commons from Google Sheets.
- Search on the Search tab. A gallery of up to 100 pictures fills in.
- Tick Save under the ones you want, or tick Save all to Collection.
- Open the Export tab. Leave Export from on Collection.
The Export tab has the columns from this post already built:
-
FILE URLS: one full-size file per line. Paste into a bulk downloader, or save as
urls.txt. -
DOWNLOAD SCRIPT: the same curl script from Step 3, with each file’s real title as its name, your email as the contact, and
sleep 1between files. Save asdownload.shand runbash download.sh. Files go to a folder calledcommons-downloads. - THUMBNAIL URLS: small previews, about 330 px wide, quick to download for a mood board.
- CREDIT LINES and CREDITS FOR A WEBSITE (HTML): because most free images need a credit, and you’ll want those too.
The script only fills in after Quick setup has saved your email on the Settings tab. Wikimedia asks every script for a contact, so the sheet won’t write one without it.
Common pitfalls
- Pasting a web page link, not a file link: the URL has to open the image itself. On Commons, use the FILE URL column, not PAGE URL.
-
Saving the script as rich text: TextEdit saves
.rtfby default. Make it plain text or the script won’t run. -
No User-Agent: Wikimedia and many other sites block or slow down requests with no contact. Keep the
-Apart. -
No pause between files: downloading hundreds of files back to back can get you rate limited. Keep
sleep 1. -
Quotes in file names: a
'in a name breaks the curl line. The SUBSTITUTE in Step 2 swaps it for_. - Huge files by surprise: videos and big scans can be hundreds of MB each. In Free Image Finder, check the MB column on Results first.
-
Running it in the wrong folder: the files land wherever Terminal is when you run it.
cdto the folder first.
Learn the Google Sheets formulas in this post
- TEXTJOIN formula: joins every command into one script cell.
- SUBSTITUTE formula: cleans characters that break file names.
- FILTER formula: how the Export tab lists only rows that have a URL.
- ARRAYFORMULA: build the whole command column with one formula instead of filling down.
Better Sheets has hundreds more tutorials like these. If you want to get better at Google Sheets, join Better Sheets.
FAQ
Can Google Sheets download images by itself?
No. Sheets can show an image from a URL with =IMAGE(), but it can’t save files to your computer. Use the sheet to write the script, then run it on your computer.
Do I need to install anything on a Mac?
No. curl comes with macOS. You only need Terminal, which is in Applications > Utilities.
How many images can I download at once?
As many as are in the list. The limit is the site you download from. Keep the one second pause and a few hundred files is fine.
Why did some files come out as tiny HTML files?
The URL was a page, not the image, or the site blocked the request. Open one in a browser to check, and make sure you’re sending a User-Agent.
Does this work for videos too?
Yes. curl doesn’t care what the file is. For free videos, see free B-roll footage that isn’t stock or AI.
Is Free Image Finder free?
Yes. Make a free Better Sheets account and copy it to your Google Drive.
Get the sheet
Free Image Finder: search, tick Save, and the Export tab writes your download script. Details on the tool page.