ZetCode

Dart parse HTML

last modified October 18, 2026

In this article we show how to parse HTML documents in Dart. We use the html package.

The package is a pure Dart implementation of an HTML5 parser, which follows the rules of the HTML specification, and of the DOM. It is the right tool for extracting data from existing documents (web scraping). It is not a browser; it does not run JavaScript.

$ dart pub add html

We need to add the html library to the project. In the web examples we also use the http package.

Dart parse local HTML file

In the first example, we parse an HTML file located on the disk.

index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>My title</title>
</head>
<body>

    <h1>My Document</h1>
    <p>
        A simple document.
    </p>
</body>
</html>

This is the file to be parsed.

main.dart
import 'dart:io';

import 'package:html/parser.dart';

void main() {
  final file = File('index.html');
  final data = file.readAsStringSync();
  final doc = parse(data);

  print(doc.head!.innerHtml);
}

We load the file and parse it. We print the inner HTML content of the head tag.

import 'dart:io';
import 'package:html/parser.dart';

We import the IO library and the HTML parser.

final file = File('index.html');
final data = file.readAsStringSync();

We read the contents of the file.

final doc = parse(data);

We parse the data into a document; this document can be processed with various member functions and attributes. The parse function never throws on malformed markup; like a browser, it repairs the tree.

print(doc.head!.innerHtml);

We get and print the contents of the head tag.

$ dart main.dart

    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>My title</title>

Dart parse HTML from a string

The parse function accepts any string, so we do not need a file. The parseFragment function parses a piece of markup without the html, head, and body elements.

main.dart
import 'package:html/parser.dart';

void main() {
  final doc = parse('<p>One<p>Two <b>bold</b>');

  print(doc.body!.innerHtml);

  final frag = parseFragment('<li>one</li><li>two</li>');
  print(frag.children.map((e) => e.text).toList());
}

The unclosed p tags are fixed by the parser, exactly as a browser would do. The fragment contains two li elements, which we read via the children property.

$ dart main.dart
<p>One</p><p>Two <b>bold</b></p>
[one, two]

Dart parse HTML from web page

In the second example, we parse an HTML document from an external web page.

main.dart
import 'package:html/parser.dart';
import 'package:http/http.dart' as http;

Future<String> fetchData() async {
  final resp = await http.get(Uri.https('example.com'));

  if (resp.statusCode == 200) {
    return resp.body;
  } else {
    throw Exception('Failed to fetch data');
  }
}

void main() async {
  final data = await fetchData();
  final doc = parse(data);

  print(doc.querySelector('title')!.text);
  print(doc.querySelector('p')!.text);
}

We make a GET request to the example.com web page and retrieve the home page. We parse it and get its title and the text of the first paragraph.

print(doc.querySelector('title')!.text);

We retrieve the text contents of the title tag with querySelector. The method returns the first matching element, or null when there is none; therefore, we must handle the nullable result (here with the ! operator).

$ dart main.dart
Example Domain
This domain is for use in documentation examples without needing permission. This is not a service; avoid relying on it for testing and monitoring purposes.

Dart html querySelectorAll

The querySelectorAll member function finds all descendant elements of this document that match the specified group of selectors.

os.html
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Operating systems</title>
</head>
<body>
    <h1>Operating systems</h1>
    <ul id="os">
        <li class="unix"><a href="https://www.oracle.com/solaris/">Solaris</a></li>
        <li class="unix"><a href="https://www.freebsd.org/">FreeBSD</a></li>
        <li class="linux"><a href="https://www.debian.org/">Debian</a></li>
        <li class="unix"><a href="https://www.netbsd.org/">NetBSD</a></li>
        <li class="windows"><a href="https://www.microsoft.com/windows/">Windows</a></li>
    </ul>
</body>
</html>
main.dart
import 'dart:io';

import 'package:html/parser.dart';

void main() {
  final doc = parse(File('os.html').readAsStringSync());
  final lis = doc.querySelectorAll('li');

  for (final e in lis) {
    print(e.text);
  }
}

The program finds all li tags in the HTML document and prints their text contents.

final lis = doc.querySelectorAll('li');

With querySelectorAll, we get all the li tags.

for (final e in lis) {
  print(e.text);
}

We go through the list and print each element's text.

$ dart main.dart
Solaris
FreeBSD
Debian
NetBSD
Windows

Dart html CSS selectors

The selectors are the same as in CSS: tag names, .class, #id, attribute selectors, and combinators.

main.dart
import 'dart:io';

import 'package:html/parser.dart';

void main() {
  final doc = parse(File('os.html').readAsStringSync());

  final unix = doc.querySelectorAll('li.unix');
  print(unix.map((e) => e.text).toList());

  final list = doc.querySelector('#os')!;
  print('${list.children.length} items');

  print(doc.querySelector('li:nth-child(3)')!.text);
  print(doc.querySelector('a[href*="debian"]')!.text);
}

We select elements by class, by id, by position with :nth-child, and by a substring of an attribute value.

$ dart main.dart
[Solaris, FreeBSD, NetBSD]
5 items
FreeBSD
Debian

Dart html attributes

Element attributes are available in the attributes map. The className and classes properties provide the class names.

main.dart
import 'dart:io';

import 'package:html/parser.dart';

void main() {
  final doc = parse(File('os.html').readAsStringSync());

  for (final a in doc.querySelectorAll('li a')) {
    final cls = a.parent!.className;
    print('${a.text.padRight(8)} $cls  ${a.attributes['href']}');
  }
}

We print the text, the class of the parent li element, and the href attribute of each link.

$ dart main.dart
Solaris  unix  https://www.oracle.com/solaris/
FreeBSD  unix  https://www.freebsd.org/
Debian   linux  https://www.debian.org/
NetBSD   unix  https://www.netbsd.org/
Windows  windows  https://www.microsoft.com/windows/

Source

Dart html library documentation

In this article we have covered HTML parsing in Dart.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Dart tutorials.