Parsing Product Images for 1C-Bitrix Catalog Population
A catalog without images doesn't sell. We know this firsthand: on one electronics e-commerce project, we needed to upload 15,000 photos from 50 suppliers. Manual upload would have taken a month. We wrote a parser that did it in two days. Recently, an auto parts store approached us with a catalog of 20,000 items. The supplier provided images only via an API, but the API returned time-limited links. We developed a script that downloaded photos in parallel, handled errors, and bound them to infoblocks. Result: a complete catalog with images in 3 days. In this article, we'll show how to automate image loading for products in 1C-Bitrix, what pitfalls exist, and how to avoid them.
How Bitrix Stores Product Images
Images are stored in the b_file table, physically in /upload/iblock/. As per the official documentation on file storage, an info-block element connects to an image through the fields:
Product images are stored in the b_file table, and connection with info-block elements is done via the PREVIEW_PICTURE and DETAIL_PICTURE fields.
-
PREVIEW_PICTURE — preview for listing (ID of record in b_file)
-
DETAIL_PICTURE — main photo for the product card
- Property of type
F (file) or G (gallery) — for additional images
For a gallery, a property of type F with flag MULTIPLE = Y is used. The standard component bitrix:catalog.element takes images from this property.
Downloading and Saving: Step-by-Step
The process consists of three stages: download the file, save via CFile, bind to the element.
// Step 1: download file (with timeout and retries)
$imageData = file_get_contents($imageUrl);
// Step 2: save via CFile::MakeFileArray()
$tmpFile = tempnam(sys_get_temp_dir(), 'img_');
file_put_contents($tmpFile, $imageData);
$fileArray = CFile::MakeFileArray($tmpFile);
$fileArray['name'] = $filename;
$fileId = CFile::SaveFile($fileArray, 'iblock');
// Step 3: bind to the gallery property
CIBlockElement::SetPropertyValuesEx($elementId, $iblockId, [
'MORE_PHOTO' => ['n0' => ['VALUE' => $fileId]]
]);
For multiple images, use indices n0, n1, n2, etc. Important: with a large number of files, use agents or queue processing to avoid execution limits.
Problems When Downloading Images
Hotlinking protection. Many source sites check the Referer. Pass the correct header:
$client->get($url, ['headers' => ['Referer' => 'https://source-site.com']]);
Image quality. Not all found photos are suitable for the catalog. Check the minimum size before saving:
$imageInfo = getimagesizefromstring($imageData);
if ($imageInfo[0] < 300 || $imageInfo[1] < 300) continue; // skip small ones
Duplicates. The same URL may appear on different pages. Cache already downloaded URL → file_id in memory or in a separate table.
Extracting Image URLs from the Source
For one main photo:
$src = $crawler->filter('.product-image img')->attr('src');
For a gallery — images are often in data-attributes or inside JavaScript. Example with data-attributes:
$crawler->filter('[data-image]')->each(function($node) use (&$urls) {
$urls[] = $node->attr('data-image');
});
If the image array is in JSON-LD, parse it with standard json_decode.
Handling Existing Images
Do not overwrite images uploaded manually or from 1C. Logic:
- Check
PREVIEW_PICTURE — if 0 or empty, add.
- For gallery — add only if the property
MORE_PHOTO is empty.
- Mark parsed images with a label in the filename (
parsed_ prefix) for later identification.
Why Parsing is More Profitable than Manual Upload?
Parsing images is 10 times faster than manual filling and costs 3-5 times less. This significantly saves the catalog filling budget.
| Parameter |
Manual Upload |
Parsing |
| Time for 10,000 photos |
20–30 working days |
2–4 days |
| Input errors |
High probability of typos and mismatches |
Minimal (after script debugging) |
| Cost |
High (payment of managers) |
Low (one-time development) |
| Scalability |
Limited by human resources |
Easily scalable to any volume |
Parsing pays off already with a catalog of 500 items. In addition, automation eliminates the "human factor" — mixed-up photos or incorrect bindings become a thing of the past.
How to Avoid Duplicates During Parsing?
Duplicates occur when the same URL is downloaded multiple times. Solution: keep track of already processed URLs. The simplest way: store an array url => file_id in script memory or in a separate HL-block. When encountering the URL again, immediately use the saved file_id.
What Our Work on Image Parsing Includes?
- Source analysis — determining page structure, access methods (API, HTML parsing), volume estimation.
- Parser development — script in PHP, taking into account source features (AJAX, protection, captcha).
- Error handling — retry on temporary failures, logging failures, notification of problems.
- Binding to infoblocks — creating new elements or updating existing ones, filling PREVIEW_PICTURE, DETAIL_PICTURE, and gallery properties.
- Testing — run on 100–500 products, checking image quality, size compliance.
- Documentation — description of script architecture, instructions for launch and support.
- Maintenance — if the source changes, we adapt the parser (support contract).
Estimated Timeline
| Stage |
Time |
| Source structure analysis |
2–4 hours |
| Downloading, validation, saving via CFile |
1–2 days |
| Binding to info-block elements (preview + gallery) |
4–8 hours |
| Error handling, retry, logging |
4 hours |
| Test run on 500 items |
4 hours |
| Total |
3–5 working days |
For catalogs over 10,000 images, add 1–2 days for parallel loading. Exact timelines depend on source complexity and quality requirements.
Our Experience and Guarantees
We have been developing on 1C-Bitrix for over 5 years and have completed 30+ catalog filling projects. Our engineers are certified and know all the nuances of the API. We guarantee that after parsing, all images will be correctly bound and duplicates excluded. Contact us for an assessment of your project — we will prepare a proposal within a day. Get a consultation on catalog automation.
Parser Development for 1C-Bitrix: Where to Start?
XMLReader, not SimpleXML — the choice of tool determines the project's fate. SimpleXML loads the entire XML into memory, and with an 800 MB supplier file, PHP will crash with a fatal error on a 512 MB limit. XMLReader processes streamingly, node by node, consuming 20–30 MB — 30 times more efficient. This detail starts any parser development for Bitrix. With over 10 years of Bitrix development and 50+ parser projects delivered, we know the pitfalls. Contact us to start your parser development today.
What Problems Does Parsing Solve?
- Primary catalog filling — 15,000 cards with descriptions, characteristics, photos. Manually, that's three months of content manager work; a parser takes a week with debugging.
- Competitor price monitoring — collecting data from Ozon, Wildberries, competitor sites. A competitor drops the price on a hot item — you find out in two hours, not two weeks.
- Supplier aggregation — five price lists in different formats (CSV with CP1251, XML in CommerceML, Excel with merged cells) become a single catalog with a unified property system.
- Card enrichment — pulling characteristics, instructions, 3D models from manufacturer sites. Without this, a product card is an SEO empty shell.
- Assortment update — products missing from the supplier feed are deactivated via
CIBlockElement::Update($ID, ['ACTIVE' => 'N']). New ones are created. The catalog stays synchronized.
What Tools Do We Use in Parser Development?
Static websites — PHP (Goutte, Symfony DomCrawler) or Python (Scrapy, lxml). Speed: 50–100 pages/sec. Sufficient for catalogs without JS rendering.
SPA and dynamic websites — Puppeteer or Playwright. Infinite scroll, AJAX filters, lazy-load images — headless browser handles it all. Speed drops to 1–10 pages/sec, but there is no alternative: data exists only after JavaScript execution.
Supplier files:
- Excel (XLS, XLSX) — PhpSpreadsheet. Beware of merged cells and formulas — they break automatic mapping.
- CSV —
fgetcsv() with correct encoding. Suppliers love CP1251, BOM in UTF-8, and semicolons instead of commas. All need detection and handling.
- XML/YML — XMLReader for large files, SimpleXML for feeds up to 50 MB.
- CommerceML — standard exchange format with 1C. We parse
import.xml and offers.xml, map to information block structure.
API — Supplier REST endpoints, marketplace APIs (Ozon Seller API, Wildberries API). We work within rate limits, handle pagination.
How Is the Auto-Population Pipeline Structured?
Four stages. Each can break in its own way.
-
Collection. Parser crawls sources via cron schedule. Raw data goes to an intermediate table — not directly into b_iblock_element. Log everything: pages visited, elements parsed, where we got 403 or timeout. Without logs, debugging a parser is like fortune-telling.
-
Normalization. Main work here:
- Clean HTML tags, extra spaces, Unicode garbage
- Units: "mm" → "mm", "millimeters" → "mm", "миллиметр" → "mm"
- Map supplier categories to Bitrix information block sections. One supplier has "Notebooks", another "Notebooks and tablets", third "Laptops" — all into one section
- Deduplication by SKU, EAN/GTIN. One product from three suppliers should not appear three times
-
Load into Bitrix. Via CIBlockElement::Add() for new elements, CIBlockElement::Update() for existing. Images: download, resize via CFile::ResizeImageGet(), convert to WebP. Properties via CIBlockElement::SetPropertyValuesEx(). SEO meta via \Bitrix\Iblock\InheritedProperty\ElementValues. SEF URLs generated from name transliteration.
-
Update. Key point — not overwrite manual edits by content manager. Update only price, stock, activity. Description and photos manually edited are flagged with UF_MANUAL_EDIT property and skipped during import. Products missing from feed are deactivated, not deleted.
Why Is Competitor Price Monitoring Necessary?
A separate subsystem with its own specifics:
| Parameter |
How It Works |
| Frequency |
From once a day to every 2 hours — depends on market volatility |
| Matching |
By SKU, EAN, fuzzy name comparison via Levenshtein distance |
| Storage |
Separate vendor_price_monitor table with history, not information blocks |
| Alerts |
Telegram/email when competitor price deviation exceeds X% |
| Auto-rules |
"Keep price 3% below competitor minimum, but not below cost + 15%" |
Result — dashboard: your product vs competitors, price history, trends. The manager sees where to raise price without losing position, and where to react.
CSV/XML Import Module: Customization for Your Format
For supplier files — custom module with admin panel:
- Configurable mapping: "column B in file → BRAND property of information block"
- Auto-detect encoding (CP1251, UTF-8, UTF-16) via
mb_detect_encoding() with validation
- Download images from URL with queue — to avoid channel saturation
- Incremental update by row hash: row changed — update, no — skip
- Cron schedule, report: created 145, updated 892, errors 3 (with details)
Large files: CSV processed in batches of 1000 rows via fgetcsv() (10 times faster than row-by-row), XML streamed via XMLReader, background execution via Bitrix agent queue — no PHP timeouts.
Legal Aspects to Consider
-
robots.txt — respect it. Crawl-delay — comply.
- Request frequency — 1–2 per second, no more. Don't DDoS someone else's site.
- Manufacturer content — use it. Unique author texts — don't copy.
- Personal data — don't collect.
What Is Included in a Turnkey Parser Development?
| Component |
Description |
| Prototype |
Parser for 1–2 sources in 2–3 days to assess data quality |
| Main parser |
Full data collection from one source (static/dynamic) |
| Bitrix import module |
Normalization, loading, update, mapping admin panel |
| Price monitoring |
If needed — collection and alert system (up to 10 competitors) |
| Documentation |
Architecture description, selector update instructions |
| Support |
3-month guarantee for uninterrupted operation, fix for donor layout changes |
How We Work and Deadlines
- Prototype — parser for 1–2 sources in 2–3 days. Assess data quality, pitfalls (Cloudflare protection, captcha, dynamic loading).
- Development — full pipeline: parser → normalization → import into Bitrix → admin panel for management.
- Testing — run on full catalog volume, check edge cases (empty fields, malformed HTML, broken images).
- Launch — configure cron, error monitoring via Telegram bot.
- Support — competitor changed layout? Update CSS selectors in parser.
| Task |
Deadlines |
| Single site parser (static HTML) |
3–5 days |
| SPA site parser (Puppeteer/Playwright, bypass protection) |
1–2 weeks |
| CSV/XML import module for Bitrix |
1–2 weeks |
| Price monitoring system (5–10 competitors) |
2–4 weeks |
| Comprehensive auto-population system |
4–8 weeks |
| Parser support and adaptation |
by subscription |
Get in touch for a free consultation — we will analyze your data sources and propose the optimal parser architecture. Request a project assessment today and get a fixed deadline. We guarantee stable parser operation and full support throughout the usage period.