# How Channel Logo URLs Are Extracted From Markdown `<img>` Tags in Free-TV/IPTV

> Discover how the Free-TV/IPTV repository extracts channel logo URLs from markdown img tags. Learn the precise string manipulation techniques used for efficient data retrieval.

- Repository: [Free TV/IPTV](https://github.com/Free-TV/IPTV)
- Tags: how-to-guide
- Published: 2026-06-17

---

**The Free-TV/IPTV repository extracts channel logo URLs by splitting markdown table rows on pipe characters, grabbing the fifth column containing the `<img>` tag, and slicing the string between `src="` and the closing quote.**

The Free-TV/IPTV project stores thousands of streaming channels in markdown tables organized by country. When the [`make_playlist.py`](https://github.com/Free-TV/IPTV/blob/main/make_playlist.py) script generates M3U playlists, it must parse these markdown tables to extract the raw image URLs from HTML `<img>` tags embedded in the *Logo* column. This extraction process uses lightweight string manipulation rather than a full HTML parser to keep the build pipeline fast and dependency-free.

## The Markdown Table Structure

Channel data lives in the `lists/` directory as markdown files (e.g., [`usa.md`](https://github.com/Free-TV/IPTV/blob/main/usa.md), [`uk.md`](https://github.com/Free-TV/IPTV/blob/main/uk.md)). Each row represents a single channel and follows this pipe-delimited format:

```markdown
| 2 | Retro TV | [>](https://example.com/stream.m3u8) | <img height="20" src="https://i.imgur.com/PNTYOgg.png" /> | RetroTVEast.us |

```

The fourth column (index 4 when split) contains the raw `<img>` tag with the logo URL stored in the `src` attribute. According to the source code, the `Channel` class receives the entire markdown line as a string and processes it to isolate this URL.

## Parsing Logic in make_playlist.py

The extraction happens in [`make_playlist.py`](https://github.com/Free-TV/IPTV/blob/main/make_playlist.py) within the `Channel` class constructor. The implementation uses two precise string operations to transform the markdown cell into a clean URL.

### Splitting the Markdown Row

First, the script splits the incoming line on the pipe character (`|`) to break the table row into individual columns:

```python
parts = md_line.split('|')
self.logo = parts[4].strip()  # Extracts: <img height="20" src="https://i.imgur.com/PNTYOgg.png" />

```

This yields the raw HTML string including the `<img>` tag and its attributes.

### Extracting the src Attribute

Next, the code locates the `src="` substring and slices the content up to the closing double quote. This is implemented in lines 104–106 of [`make_playlist.py`](https://github.com/Free-TV/IPTV/blob/main/make_playlist.py):

```python
self.logo = self.logo[self.logo.find('src="') + 5:self.logo.rfind('"')]

```

The `find('src="') + 5` calculation skips past the `src="` prefix (5 characters), while `rfind('"')` locates the final quote of the attribute. The result is the pure URL: `https://i.imgur.com/PNTYOgg.png`.

## Code Example: Extracting a Logo URL

You can observe this behavior by instantiating the `Channel` class directly with a markdown line:

```python
from make_playlist import Channel

group = "USA"
md_line = '| 2 | Retro TV | [>](https://example.com/stream.m3u8) | <img height="20" src="https://i.imgur.com/PNTYOgg.png" /> | RetroTVEast.us |'

ch = Channel(group, md_line)
print(ch.logo)  # Output: https://i.imgur.com/PNTYOgg.png

```

This manual parsing approach assumes the `src` attribute always uses double quotes and appears before any other attributes in the closing tag.

## Generating the M3U Output

Once extracted, the logo URL is stored in `self.logo` and later injected into the M3U playlist as the `tvg-logo` attribute. The `to_m3u_line()` method formats the entry as:

```

#EXTINF:-1 tvg-name="Retro TV" tvg-logo="https://i.imgur.com/PNTYOgg.png" group-title="USA",Retro TV
https://example.com/stream.m3u8

```

This metadata allows IPTV players to display the channel icon alongside the stream name.

## Summary

- **Location**: Extraction logic resides in [`make_playlist.py`](https://github.com/Free-TV/IPTV/blob/main/make_playlist.py), lines 104–106 within the `Channel` class.
- **Method**: The script splits markdown rows on pipe characters, selects the fifth element (index 4), and slices between `src="` and the closing quote.
- **Output**: The resulting URL populates the `tvg-logo` attribute in the generated M3U playlist.
- **Trade-off**: String slicing is used instead of an HTML parser for performance, requiring strict adherence to the `<img src="...">` format in the markdown tables.

## Frequently Asked Questions

### Why does the repository use manual string parsing instead of an HTML parser?

The Free-TV/IPTV project favors manual string slicing over libraries like BeautifulSoup or html.parser to minimize dependencies and keep the build script lightweight. Since the markdown format is strictly controlled and generated by the maintainers, simple string manipulation is reliable and executes faster than parsing full HTML documents.

### What happens if the img tag format changes?

If contributors modify the `<img>` tag structure—such as using single quotes for the `src` attribute or reordering attributes—the current parsing logic in [`make_playlist.py`](https://github.com/Free-TV/IPTV/blob/main/make_playlist.py) would fail to extract the URL correctly. The `find('src="')` method specifically searches for double quotes, so any deviation would require updating lines 104–106 to match the new pattern.

### Where are the markdown files with channel data located?

The channel data resides in the `lists/` directory at the root of the repository. Each country has its own markdown file (e.g., [`usa.md`](https://github.com/Free-TV/IPTV/blob/main/usa.md), [`germany.md`](https://github.com/Free-TV/IPTV/blob/main/germany.md)) containing tables where each row includes the channel number, name, stream URL, logo `<img>` tag, and EPG ID.

### How is the extracted logo URL used in the final playlist?

The extracted URL is assigned to the `tvg-logo` attribute in the M3U playlist's `#EXTINF` directive. This metadata tag is the standard way IPTV applications associate thumbnail images with specific channels, allowing players to display the logo in the channel guide and interface.