How to scrape commodities and trading data from T-Bank using the Minexa API
- Minexa.ai

- Jul 7
- 5 min read
The T-Bank invest portal lists dozens of ETFs and investment funds on a single paginated page. Each card carries a fund name, a logo, a performance chart rendered in SVG, and a link to the fund detail page. Visually, it reads cleanly. Programmatically, it is a different story: the chart data is embedded in SVG polyline attributes, gradient identifiers are scattered across path elements, and performance direction is encoded in CSS variable names rather than plain text values. Getting that into a usable dataset without a structured extraction layer means writing and maintaining custom parsing logic for every field.
The Minexa API handles this differently. You train a scraper once using the Minexa Chrome extension, get back a stable scraper ID, and then call the API with that ID and the URLs you want to process. The output is structured JSON, with every SVG attribute, gradient reference, and CSS variable already parsed into typed field objects you can work with directly.
This post walks through the full workflow for extracting ETF data from T-Bank (tbank.ru/invest/etfs/) using the Minexa API, from training the scraper to reading the output fields.
Watch the extraction walkthrough first
The video below covers the full process from opening the Minexa extension on the T-Bank ETF page to reviewing the extracted data and accessing the API request details.
What the page looks like before extraction
Open tbank.ru/invest/etfs/ and you see a grid of fund cards. Each card has a fund theme label in Russian, a small performance sparkline, and a logo. The page loads with JavaScript and paginates in batches of twelve, appending URL parameters like ?start=12&end=24 as you move through pages.
None of that data is accessible in a structured form from the page itself. The sparkline is an SVG element with polyline coordinates. The gradient that fills the chart area references a dynamically generated ID. The color of the chart line is set via a CSS custom property, not a hex value. Extracting any of this manually would require parsing SVG markup and resolving CSS variable references, per card, per page.
After the Minexa API processes the same page, each of those elements becomes a named field in a clean JSON record. The contrast between what you see on the page and what comes back from the API is where the value of the extraction layer becomes concrete.
Training the scraper: the one-time setup
The Minexa developer workflow has two phases. Phase one is training: you use the Chrome extension to point Minexa at the page, confirm what it detected, and generate a scraper configuration. Phase two is calling the API with that configuration on any number of URLs.
After opening the extension on the T-Bank ETF page, Minexa detects the repeating card structure automatically. You confirm you are on the right page, review the pagination detection, and choose whether to scrape the list only or follow each fund link to extract detail page data as well.
Pagination on T-Bank uses URL parameters. When using the API, you will need to supply each paginated URL explicitly or write a JS code scenario that handles the click logic. Automatic pagination handling is available only through the Chrome extension workflow, not through direct API calls.
Once you select simple mode and highlight the card container, Minexa identifies all data points within each card and generates the scraper. This takes a few seconds. The scraper ID it returns is what you use in every subsequent API call.
After training, the extension shows you the extracted data points and gives you access to the API request code directly.
Copy the scraper ID from that screen. You will use it in the API request body shown below.
Calling the API
Once the scraper is trained, extraction is a single POST request. Here is a working Python example using the scraper ID generated during training:
import requests
url = "https://api.minexa.ai/data"
payload = {
"scraper_id": 6271,
"urls": [
"https://www.tbank.ru/invest/etfs/",
"https://www.tbank.ru/invest/etfs/?start=12&end=24&country=All&orderType=Desc&sortType=ByName"
],
"columns": "top_20"
}
headers = {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.json())
Pass each paginated URL as a separate entry in the urls array. The columns parameter accepts either a top_N shorthand or a list of named fields if you want to limit the output to specific columns.
What the output looks like: raw page vs structured API response
Here is what the API returns for two ETF cards from the T-Bank listing. Field name prefixes have been removed for readability:
[
{
"etf_link": "/invest/etfs/TRND@/",
"investment_themes": "Трендовые акции",
"brand_logo_url": "//invest-brands.cdn-tinkoff.ru/TRNDx160.png",
"stroke_color": "var(--tui-status-positive)",
"chart_data": [
{ "value": "0,29.1 8,27.41 15,16.73 23,13.35 30,19.40", "tag": "polyline", "attribute": "points", "type": "attribute" },
{ "value": "TRND@", "tag": "lineargradient", "attribute": "id", "type": "attribute" },
{ "value": "url(#TRND@)", "tag": "path", "attribute": "fill", "type": "attribute" }
],
"style_attribute": "stop-color: var(--tui-status-positive); stop-opacity: 0.05;"
},
{
"etf_link": "/invest/etfs/TITR@/",
"investment_themes": "Российские Технологии",
"brand_logo_url": "//invest-brands.cdn-tinkoff.ru/TITRx160.png",
"stroke_color": "var(--tui-status-negative)",
"chart_data": [
{ "value": "0,14.58 8,14.73 15,7.99 23,5.90 30,15.63", "tag": "polyline", "attribute": "points", "type": "attribute" },
{ "value": "TITR@", "tag": "lineargradient", "attribute": "id", "type": "attribute" },
{ "value": "url(#TITR@)", "tag": "path", "attribute": "fill", "type": "attribute" }
],
"style_attribute": "stop-color: var(--tui-status-negative); stop-opacity: 0.05;"
}
]
The contrast with the raw page is immediate. On the page, the polyline coordinates exist inside an SVG element with no label. In the API output, they are a typed object with a tag, attribute name, and value you can parse directly. The gradient ID that links the fill area to its color definition is captured as a separate object in the same array, so you can resolve the visual relationship between chart line and fill without inspecting the DOM.
Key fields and what they tell you
The chart_data field is the most information-dense field in the output. It returns an array of typed objects, each representing one SVG element that contributes to the sparkline. A single card can produce four objects in this array: the polyline point sequence, the linear gradient ID, the closed SVG path string, and the fill attribute reference. When chart_data contains only a dash character as a text node, it means the fund has no historical price data available yet.
The stroke_color field surfaces the CSS variable assigned to the chart line. Two values appear across the dataset: var(--tui-status-positive) and var(--tui-status-negative). This is the only machine-readable signal in the listing that indicates whether a fund's recent trend is up or down. You can use this field to filter or group funds by direction without parsing the coordinate sequence.
The unique_identifier and url_identifier fields behave differently depending on the card. For funds with active chart data, both fields are empty strings. For funds without chart data, both fields capture the linear gradient ID from the SVG element. The url_identifier additionally captures the fill attribute reference in a second object within the array. This means you can use the presence or absence of a value in these fields as a proxy for whether a fund has chart data, without reading the chart_data field directly.
The etf_link field provides the relative path to each fund's detail page. Prepend the base domain to construct a full URL you can pass back into the API to extract fund-level detail data in a second extraction pass.
Running at scale
Once the scraper is trained, calling it against additional pages costs nothing in setup time. You supply the URLs, the API processes them, and the output schema stays consistent across every page. If T-Bank adds new funds and the page structure remains the same, no retraining is needed. If the site redesigns its card layout, retraining takes the same few minutes as the original setup.
For ongoing monitoring, you will need to manage your own scheduling. Set up a cron job that builds the paginated URL list and calls the API on whatever cadence your use case requires. The API does not manage scheduling on your behalf when called directly.
If you want to explore the full API parameter reference, the Minexa API documentation covers request structure, column selection options, and credit consumption details: minexa.stoplight.io/docs/minexa.
For a related example using financial and trading data from a different source, see: Scraping TradingView bond ideas with the Minexa.ai API.

Comments