yandex-reverse-image-api
A Python client for Yandex reverse image search through ScrapingBee. One method per result tab, plus the check that tells a bad input apart from a genuine no match.
Verified live on 2026-09-10 against two real images. Every return value below is the actual output of the sweep, including the two that came back empty and the reason each did.
pip install yandex-reverse-image-api
Requires Python 3.8 or newer and requests.
Read this before you budget
Every call costs 75 credits, and the cheap request does not work.
A 1 credit fetch of a reverse image URL returns HTTP 200 with a 14,885 byte page titled Are you not a robot?, carrying Yandex SmartCaptcha. Nothing in the status code tells you the scrape failed. spb-initial-status-code reads 302.
Stealth clears it, and there is no working middle rung between 1 and 75. So reverse image search on Yandex is 75 credits per lookup, full stop. At the entry paid tier of 250,000 credits that is about 3,300 lookups a month.
ScrapingBee does not cache. Reverse image results for a fixed image change slowly, so cache them yourself.
Authentication
from yandex_reverse_image_api import YandexReverseImage
bee = YandexReverseImage("YOUR_API_KEY")
Sent as Authorization: Bearer YOUR_API_KEY. Key and 1,000 free credits: ScrapingBee. Landing page: Yandex reverse image API.
Where the data lives
Not in the DOM. Yandex renders its result grid client side and ships the payload in data-state attributes as HTML escaped JSON, so extract_rules and CSS selectors both match nothing on this target. There are no result nodes in the markup to select.
This client finds every data-state attribute, unescapes it, loads the JSON and reads the slice you asked for off initialState. Yandex calls the feature CBIR, content based image retrieval, and that acronym prefixes every slice name.
Method reference
sites(image_url)
The main event. Every page where the image appears. Uses cbir_page=sites.
matches = bee.sites("https://upload.wikimedia.org/wikipedia/commons/3/3c/Shaki_waterfall.jpg")
len(matches) # 37
{'domain': 'en.wikipedia.org',
'title': 'Shaki Waterfall - Wikipedia',
'description': 'Shaki Waterfall. ',
'url': 'https://en.wikipedia.org/wiki/Shaki_Waterfall?utm_medium=organic&utm_source=yandexsmartcamera',
'clean_url': 'https://en.wikipedia.org/wiki/Shaki_Waterfall',
'thumb': 'https://avatars.mds.yandex.net/i?id=eb74556e...',
'width': 960,
'height': 719,
'original_image': 'https://upload.wikimedia.org/.../960px-Shaki_waterfall.jpg'}
Two normalisations the client applies, because both bite otherwise:
clean_urlstrips the query string. Yandex appends?utm_medium=organic&utm_source=yandexsmartcamerato every result URL, which breaks deduplication if you compare raw URLs.thumbis made absolute. Yandex returns it protocol relative, starting with//.
width and height are the dimensions of the copy hosted on that page, not of your input, which is how you find the highest resolution copy of an image in the wild.
domains(image_url)
Match count per domain, deduplicated on clean_url.
bee.domains(image_url)
# {'bestofarmenia.com': 2, 'armeniantrip.com': 2, 'yandex.ru': 2,
# 'hotel.am': 2, 'eastroute.com': 2, 'ug-ideal.ru': 2, ...}
The shape most brand protection and counterfeit detection work actually wants.
similar(image_url)
Visually similar images. Uses cbir_page=similar. Returned 40 thumbs on the test image.
products(image_url)
Shopping matches for the object. Uses cbir_page=products. Returned 0 on the test image, which is correct: a landscape photograph has no shopping match. Expect real entries on product photos.
ocr(image_url)
Text recognised inside the image.
bee.ocr(image_url)
# {'hasText': False, 'plainText': '', 'blocks': [], 'entities': [], ...}
hasText was False on the test image, because a waterfall photograph has no text in it. That is the right answer, not a failure.
This costs no extra credits. OCR arrives in the same response as the default tab, so one 75 credit call gives you reverse image matches and the text inside the image with no separate step.
tags(image_url)
Yandex's own category labels. Returned 5 tags on the test image.
other_sizes(image_url)
The same image at other resolutions, grouped into buckets.
bee.other_sizes(image_url)
# {'small_dups': [...6...], 'medium_dups': [...6...], 'large_dups': [...6...]}
check_image(image_url)
Run this first on any image you have not searched before.
bee.check_image("https://upload.wikimedia.org/wikipedia/commons/3/3c/Shaki_waterfall.jpg")
# {'expired': False, 'width': 1024, 'height': 767, 'usable': True}
Yandex fetches your image from the URL before it searches. If its crawler cannot reach the file, or the URL is a short lived derivative, you get a valid page with an empty result set and no error message at all.
Three images, same configuration, same stealth tier:
| Image | cbirPreview |
Result |
|---|---|---|
| Wikimedia Commons full size JPEG | expired: False, 1024x767 |
37 sites, 40 similar, 5 tags |
A Wikimedia thumb/ derivative URL |
expired: True |
0 matches |
A nasa.gov PNG |
expired: True, width 0, height 0 |
0 matches, pageSize: 0 |
So an empty sites list plus usable: False is an input problem. An empty sites list with real dimensions is a genuine no match. Without this check the two are indistinguishable, and you will record "no matches found" for images that were never searched.
Hand Yandex a stable, directly addressable, full size URL.
tab_url(image_url, cbir_page=None)
A static method. 0 credits, no request. Builds the Yandex URL for one tab.
YandexReverseImage.tab_url(img, "sites")
# 'https://yandex.com/images/search?rpt=imageview&cbir_page=sites&url=https%3A%2F%2F...'
The four tab forms were read out of the live page's own cbirNavigation.menuItems, not guessed:
| Tab | cbir_page |
|---|---|
| Search by image | omit it |
| Similar | similar |
| Sites | sites |
| Products | products |
Note the double encoding: the image URL is percent encoded inside the Yandex URL, which is then passed as the ScrapingBee url parameter. This is the most common place a hand rolled version breaks.
usage()
Free. Account credits, concurrency and renewal date.
Credit cost
Measured from spb-cost headers. Available on bee.last_cost.
| Configuration | Credits | Outcome |
|---|---|---|
mode=auto |
1 | SmartCaptcha page |
stealth_proxy=true |
75 | Real results |
| Validation error | 0 | Nothing billed |
stealth_proxy forces JavaScript rendering, and mode=auto is incompatible with it. Sending both returns HTTP 400 and bills nothing, which fails quietly.
Every method here is one call, so nine methods on one image is 675 credits. If you need several tabs for the same image, note that ocr, tags, other_sizes and check_image all read the default tab, so fetching once and parsing four slices locally is a single 75 credit charge.
Plan tiers: ScrapingBee pricing.
Related
Other visual search landing pages: Yandex images API, Yandex search API, Google reverse image API, Google Lens API, Google image scraper, Bing reverse image search API, Bing images API, eBay image search API, Naver images API, Yahoo images API, Getty images scraper API, website image API, images results API, Amazon image API.
Features: AI web scraping, JavaScript scenario for driving the upload widget instead of passing a URL, screenshots, markdown scraper, data extraction.
The Yandex text search walkthrough is at how to scrape Yandex search results. Tab by tab guide: github.com/ScrapingBee/yandex-reverse-image-api.
License
MIT
Metadata
Release files for yandex-reverse-image-api 0.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| yandex_reverse_image_api-0.0.1.tar.gz | 12.0 kB | Without provenance | Details for yandex_reverse_image_api-0.0.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| yandex_reverse_image_api-0.0.1-py3-none-any.whl | Python 3 | none | any | Details for yandex_reverse_image_api-0.0.1-py3-none-any.whl |
Total release size: 22.1 kB
Release files / yandex_reverse_image_api-0.0.1.tar.gz
| Download URL | yandex_reverse_image_api-0.0.1.tar.gz |
|---|---|
| Size | 12.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
fa2109eefbb205c74bd2c79af8c32f6da6f6db21230b08e1b694833fa7e4c7b6
|
|
BLAKE2b-256 checksum How to use checksums |
4dd477638280778aedef40e716e84d4abede199530caee0bf1da7084a117ea98
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.3
|
Release files / yandex_reverse_image_api-0.0.1-py3-none-any.whl
| Download URL | yandex_reverse_image_api-0.0.1-py3-none-any.whl |
|---|---|
| Size | 10.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
12b902248ca41da6c71513104ad11a2fc344b5e3fdab35bdc12c0c5400ced985
|
|
BLAKE2b-256 checksum How to use checksums |
f28b8d7bddae7117576d3031c237e33afa68945e283d50743459cf197bdb4d3a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.3
|
Security for yandex-reverse-image-api 0.0.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.