Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Scan for outdated or missing drivers - takes under a minute3Clear out junk files and repair common Windows errorsSome links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
To automate a download with Python and GNU Wget, run the installed wget executable through Python’s built-in subprocess module. The three useful patterns are: download to Wget’s default filename, choose a destination with -O or -P, and ask Wget to continue a partial download with -c. Wget is an external program—not a feature that Python installs automatically—and resuming depends on the server and the existing file.
What “Python wget” means
GNU Wget is a command-line downloader that a Python program can launch. Python’s subprocess module starts the external process; it does not provide Wget itself. The GNU Wget manual describes it as “a free utility for non-interactive download of files from the Web.” In the examples below, wget must resolve to an executable in the environment where the script runs.
This is distinct from the Python package named wget on PyPI. That project documents a python -m wget command and a wget.download(url) API. Those are not the same interface as the GNU Wget executable. If you intend to use the examples here, install and verify GNU Wget rather than assuming that installing a Python package provides the command.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Check the prerequisites
- Install GNU Wget. Use the current instructions for your operating system and package manager. Installation commands can change, and the command available on one system may differ from another; verify the current package-manager guidance for your environment.
- Confirm the executable is available where Python runs. In a terminal, try
wget --version. If that works interactively but not in your script, check the script’sPATHand execution environment. Containers, scheduled jobs, virtual machines and hosted runtimes may not inherit the same setup as your terminal. - Use Python 3. The code below uses
subprocess.run, argument lists andpathlib. It avoids shell command construction, which also avoids a common source of quoting and injection problems when URLs or filenames contain special characters. - Choose a writable destination. Relative paths are relative to the script’s current working directory, which may not be the directory containing the script. Use an explicit path if the location matters.
Command 1: download using the URL’s default filename
Pass the URL as a separate argument to subprocess.run. GNU Wget downloads a URL supplied on its command line and ordinarily derives the local filename from the URL.
#1 Best Overall
import subprocess
url = "https://getsamplefiles.com/download/zip/sample-1.zip"
result = subprocess.run(["wget", url], check=True)
print(f"Download finished (exit code {result.returncode})")
The sample address is illustrative, not a promise that the endpoint will remain available. Replace it with a URL you are authorized to retrieve. With check=True, Python raises subprocess.CalledProcessError if Wget exits unsuccessfully, rather than silently proceeding as if the download succeeded.
Wget may print progress and diagnostic messages to the terminal. By default, subprocess.run lets the child process use the parent process’s standard input, output and error streams. That is useful for an interactive script. For a scheduled job or an application that needs to record diagnostics, you can capture output and inspect it:
import subprocess
url = "https://getsamplefiles.com/download/zip/sample-1.zip"
try:
result = subprocess.run(
["wget", url],
check=True,
capture_output=True,
text=True,
timeout=120,
)
except FileNotFoundError as exc:
raise RuntimeError("GNU Wget is not available on PATH") from exc
except subprocess.TimeoutExpired as exc:
raise RuntimeError("Wget did not finish before the timeout") from exc
except subprocess.CalledProcessError as exc:
print("Wget reported an error:", exc.stderr)
raise
else:
print(result.stdout)
The timeout is an application choice, not a universal safe limit. Set it to fit the expected file size and network conditions. A timed-out subprocess is stopped by Python; a partial file may remain, so decide whether the next run should keep it and attempt continuation or remove it before starting over.
Command 2: choose the output filename or directory
GNU Wget has two different destination options. Use -O (output document) when you want to specify the output file path. Use -P (directory prefix) when you want Wget to save using its usual filename inside a chosen directory.
Rank #2
Choose a specific file with -O
from pathlib import Path
import subprocess
url = "https://getsamplefiles.com/download/zip/sample-1.zip"
out_file = Path("downloads") / "sample.zip"
out_file.parent.mkdir(parents=True, exist_ok=True)
subprocess.run(["wget", "-O", str(out_file), url], check=True)
print(f"Saved to {out_file.resolve()}")
Creating the parent directory in Python makes the example’s destination setup explicit. This command overwrites the named output document if it already exists; if you need to preserve an existing file, choose a different path or define an explicit policy before running the download.
Be careful using -O with multiple URLs: the GNU Wget manual specifies that output-document behavior can concatenate downloaded content. It is not a general instruction to create a separate named file for every URL. For a list of URLs that should each retain their own filename, use Wget’s normal per-URL behavior, or run one download per subprocess call with a separately chosen destination.
Choose a directory with -P
from pathlib import Path
import subprocess
url = "https://getsamplefiles.com/download/zip/sample-1.zip"
out_dir = Path("downloads")
out_dir.mkdir(parents=True, exist_ok=True)
subprocess.run(["wget", "-P", str(out_dir), url], check=True)
Here Wget chooses the filename while placing the downloaded document in downloads. This is often a better fit than -O when retrieving more than one URL and you want each to use its URL-derived name. If filenames may collide, plan how to handle that before running a batch.
Command 3: attempt to continue a partial download
Pass -c (the short form of --continue) to ask Wget to continue a partial file. This is an attempt, not a guarantee: continuation depends on the server’s response, the URL still referring to the expected content, and the local partial file being suitable to continue.
from pathlib import Path
import subprocess
url = "https://getsamplefiles.com/download/zip/sample-1.zip"
out_dir = Path("downloads")
out_dir.mkdir(parents=True, exist_ok=True)
subprocess.run(["wget", "-c", "-P", str(out_dir), url], check=True)
Use the same destination directory and URL as the interrupted download so Wget can find the existing partial file. If the remote content changed, the server does not support the needed range behavior, or the local file is not a partial copy of the same resource, continuation may fail or produce an unsuitable result. Validate the completed file in the way appropriate to its format and use case.
For a fixed custom filename, combine continuation with the same -O path used before. Keep the destination consistent between runs; changing the path means Wget will not be continuing the old file there.
Passing several URLs safely
Wget can accept more than one URL on its command line and will download the URLs supplied. In Python, keep each URL as an individual list element rather than joining them into a shell string:
Recommended Free Tools
import subprocess
urls = [
"https://example.com/first.zip",
"https://example.com/second.zip",
]
subprocess.run(["wget", *urls], check=True)
This uses Wget’s normal filename behavior. Do not add a single -O some-file if you expect separate output files; that option’s multiple-URL behavior is different. For per-file custom names, iterate and invoke Wget once per URL, choosing a destination for each call.
Handling errors, paths and downloaded content
A successful process exit is useful evidence that Wget completed its operation, but it does not by itself prove the downloaded content is the file your application expects. A server might return an error page, a login page or another unexpected response at a URL. For important downloads, validate the result rather than relying solely on the filename or exit code.
- Missing executable:
FileNotFoundErrorusually means the command is not installed or is not on the script’sPATH. Install GNU Wget in the actual runtime environment or configure the executable path. - Nonzero exit status: With
check=True, this becomesCalledProcessError. Inspect Wget’s error output and check the URL, connectivity, permissions and server response. - Permission denied: Select a directory the running user can write to. Do not assume a scheduled task runs as the same user as your terminal.
- Unexpected file location: Resolve relative paths against the process working directory, or use an absolute destination built with
Path. - Timeout or interruption: Check whether a partial file remains. Resume only when you intend to continue the same resource and destination; otherwise remove or rename the partial file according to your application’s policy.
- Bad or incomplete content: Check the response and validate the downloaded data—for example, by checking an expected format or checksum when one is available from a trusted source.
A production downloader may also need retry limits, logging, disk-space checks, content validation, concurrency limits, and a policy for replacing existing files. The minimal examples above do not implement those application-specific safeguards.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.When to use GNU Wget versus Python’s standard library
Python’s urllib.request can retrieve a resource without installing a separate command-line executable. Python 3.13 documentation describes urllib.request.urlretrieve(url, filename=...) as a way to copy a network resource to a local file, and also documents urlopen for reading a response.
from pathlib import Path
from urllib.request import urlretrieve
url = "https://getsamplefiles.com/download/zip/sample-1.zip"
out_file = Path("downloads") / "sample.zip"
out_file.parent.mkdir(parents=True, exist_ok=True)
urlretrieve(url, out_file)
print(f"Saved to {out_file.resolve()}")
The Python documentation notes that urlretrieve may raise ContentTooShortError if the response is shorter than the amount stated in the Content-Length header. If the server supplies no Content-Length, the function cannot use that check to detect a short response. Add exception handling, timeouts and validation that fit your application; this short example is not a complete robust downloader.
Best Value
| Consideration | GNU Wget through subprocess |
urllib.request |
|---|---|---|
| External executable | Requires GNU Wget to be installed and discoverable in the runtime environment. | Uses Python’s standard library; no Wget executable is required. |
| Wget-specific command-line behavior | Useful when the task needs Wget options such as continuing a partial download or other command-line capabilities. | Does not invoke Wget’s command-line options; use Python APIs for response handling. |
| Python-native control flow | Python handles process launch and exit status; Wget performs the transfer. | Python code handles retrieval and exceptions directly. |
| Deployment | Ensure Wget is installed wherever the script runs, not only on a developer’s workstation. | Avoids managing that executable, though network, path and error handling still matter. |
Neither approach is the universal winner. Choose Wget if its installed executable and options suit the deployment; choose the standard library when avoiding an external program or handling the response directly in Python matters more.
Or skip the browser setup
If the task is to capture a rendered webpage as an image or PDF—not to download an arbitrary file—ScreenshotNeo is a separate option. It is a website screenshot API and MCP server, so it does not replace Wget for ZIP files or other direct file downloads. One GET request can return a screenshot or PDF. The API also removes cookie/consent banners, newsletter popups and chat widgets before capture; bot checks, blank pages and failed loads are never billed; an MCP server lets AI agents take screenshots; and the free plan includes 1,000 screenshots per month with no card, while paid plans start at $5 for 3,000. See the ScreenshotNeo API documentation.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Sign up for 1,000 free screenshots a month, with no card required.
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minutePC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Frequently Asked Questions
Is pip install wget required for the examples?
No. The examples invoke the GNU Wget executable through Python’s built-in subprocess. The separately named PyPI project is a different interface.
Can I use these commands on Windows?
Yes, provided GNU Wget is installed and available to the process. Installation and PATH configuration vary, so verify them in the environment that runs the script.
Does -c guarantee a download will resume?
No. It requests continuation, but the server response, local partial file and resource identity determine whether continuation is possible.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

