python
urllib
image-download
programming-tutorial
web-scraping

Downloading a picture via urllib and python

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Python's standard-library urllib package is enough to download an image when you do not want an extra dependency such as requests. The core workflow is simple: open the URL, read the bytes, and write them to a local file in binary mode.

Basic Download with urllib.request

The low-level pattern uses urlopen and manual file writing.

python
1from urllib.request import urlopen
2
3url = "https://httpbin.org/image/png"
4output_path = "image.png"
5
6with urlopen(url) as response:
7    image_bytes = response.read()
8
9with open(output_path, "wb") as f:
10    f.write(image_bytes)

This works because images are binary data. Opening the output file with "wb" is required so Python does not treat the bytes as text.

A Convenient Shortcut with urlretrieve

For simple downloads, urlretrieve is more compact.

python
from urllib.request import urlretrieve

urlretrieve("https://httpbin.org/image/jpeg", "photo.jpg")

This is convenient for small scripts, but many developers prefer urlopen because it gives more control over response handling and errors.

Add Basic Error Handling

Network code should assume failure is possible. Invalid URLs, timeouts, redirects, and permission problems can all happen.

python
1from urllib.request import urlopen
2from urllib.error import URLError, HTTPError
3
4url = "https://httpbin.org/image/png"
5
6try:
7    with urlopen(url, timeout=10) as response:
8        if response.status != 200:
9            raise RuntimeError(f"unexpected status: {response.status}")
10
11        data = response.read()
12
13    with open("downloaded.png", "wb") as f:
14        f.write(data)
15
16except HTTPError as exc:
17    print(f"HTTP error: {exc.code}")
18except URLError as exc:
19    print(f"URL error: {exc.reason}")

That pattern is more realistic than a raw download because production code has to handle failure cases explicitly.

Choosing the File Name

Sometimes the URL does not contain a reliable file name or extension. In that case, choose the local name yourself rather than trying to infer too much from the URL. If the server provides a Content-Type header, you can inspect it, but saving with a known output name is often simpler.

For example:

  • use a timestamped name for scraped datasets
  • use a stable deterministic name for repeatable downloads
  • use a temporary file if the image is only an intermediate artifact

Add Headers When a Server Expects Them

Some servers reject bare default requests or return a different response unless a user agent is present. In those cases, create a Request object and attach headers explicitly.

python
1from urllib.request import Request, urlopen
2
3request = Request(
4    "https://httpbin.org/image/png",
5    headers={"User-Agent": "Mozilla/5.0"}
6)
7
8with urlopen(request) as response:
9    data = response.read()
10
11with open("header-example.png", "wb") as f:
12    f.write(data)

This does not override site policy, but it can make a legitimate scripted request behave more like a normal browser fetch when the server expects a minimal header set.

Respect the Source Site

Downloading images programmatically can move into scraping territory quickly. Before crawling many files, check the site's terms, robots guidance where relevant, and rate limits. The fact that a URL is reachable does not automatically mean bulk downloading is appropriate.

For one-off internal or tutorial cases, the technical mechanics are easy. At scale, polite request behavior matters just as much as the code.

Common Pitfalls

  • Opening the output file in text mode corrupts binary image data. Always write image content with "wb".
  • Ignoring HTTP and URL errors makes failures look like empty or broken files. Handle HTTPError and URLError explicitly.
  • Assuming the URL always implies a good file extension can produce confusing local files. Choose or validate the output name yourself.
  • Downloading large files with response.read() into memory may be wasteful. For bigger payloads, stream in chunks instead of reading everything at once.
  • Treating bulk image download as a purely technical task can cause policy or rate-limit problems. Be respectful of the source site and its usage rules.

Summary

  • 'urllib.request can download pictures without any third-party package.'
  • Use urlopen for control or urlretrieve for a quick one-liner.
  • Write image data to disk in binary mode.
  • Add error handling for HTTP and network failures.
  • For larger or repeated downloads, think about naming, streaming, and source-site constraints.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.