Skip to content
/ hred Public

Reduce HTML and XML to JSON from the command line, using an expressive query language inspired by CSS selectors.

License

Notifications You must be signed in to change notification settings

danburzo/hred

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

45 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

hred

npm version

hred (html reduce) is a command-line tool to extract data from HTML. It reads HTML from the standard input and outputs the JSON produced by a qsx query:

> curl https://danburzo.ro/rolodex/ | hred "article a { @href, @.textContent }"
[
  {
    "href": "http://www.3quarksdaily.com/",
    ".textContent": "3 Quarks Daily"
  },
  {
    "href": "http://50watts.com",
    ".textContent": "50 Watts"
  },
  {
    "href": "http://aworkinglibrary.com/",
    ".textContent": "A Working Library"
  },
  ...
]

The qsx documentation describes the kinds of queries you can make with hred, but if you're familiar with CSS selectors you're mostly good to go.

Installation

hred runs on Node.js. You can find hred in the npm registry:

# install hred globally with npm:
npm install -g hred

# install hred globally with yarn:
yarn global add hred

# run hred without installing it:
npx hred 

Usage

hred accepts a qsx query string:

curl https://en.wikipedia.org/wiki/Banana | hred "img { @alt, @src }"

[
  {
    "alt": "Page semi-protected",
    "src": "//upload.wikimedia.org/wikipedia/en/thumb/1/1b/Semi-protection-shackle.svg/20px-Semi-protection-shackle.svg.png"
  },
  {
    "alt": "Banana and cross section.jpg",
    "src": "//upload.wikimedia.org/wikipedia/commons/thumb/f/ff/Banana_and_cross_section.jpg/250px-Banana_and_cross_section.jpg"
  },
  ...
]

hred has the single, modest purpose of extracting parts of HTML as JSON. Because the qsx query language is a lightweight extension to the CSS selector syntax used by the Element.querySelectorAll() DOM method, hred offers only limited reshaping of the resulting JSON via aliases. The tool is designed to be piped to something like jq if further JSON processing is necessary.

hred has a few options available:

Option Description
-c, --concat if the result is an array, return it as concatenated JSON records, to make it easier to collate several results together
-f <queryfile>, --file=<queryfile> read the query from an external file instead of passing it as an operand
-h, --help print help message
-r, --raw a complement to -c that returns raw (unquoted) strings when the result is an array of strings
-u <url>, --url=<url> add the base URL against which the HTML should be evaluated; influences the value of the DOM properties @.href, @.src when the HTML attributes are relative
-V, --version display the current version
-x, --xml parse the input as XML rather than HTML

A real-life example

Let's take a web page that uses atomic, presentational CSS rather than semantic CSS classes (and thus makes it more challenging to extract data), such as my starred repos page. To extract info about the repositories, at the time of writing:

curl https://github.com/danburzo\?tab\=stars | hred "
.mb-1 {
	h3 a ...{ 
		@href => url , 
		@.textContent => title 
	}, 
	^ :scope ~ .py-1 @.textContent => description 
}"

Let's break the query apart:

For each element with the class mb-1:

  1. on the one hand, find <a> elements nested into <h3>s:
    1. read their href HTML attribute as url and their textContent DOM property as title;
    2. merge the resulting object into the current scope with >> .;
  2. on the other hand, find the first (^) subsequent element (:scope ~) that matches the class py-1
    1. extract its textContent as description.

The resulting JSON, abridged:

[
  {
    "url": "/urfave/cli",
    "title": "\n        urfave / cli\n      ",
    "description": "\n      \n        A simple, fast, and fun package for building command line apps in Go\n      \n  "
  },

A note on security

hred uses as its DOM environment jsdom, which has the ability to run the JavaScript included in web pages. Because scripts specially crafted to attack jsdom may potentially evade the sandbox to which their execution is confined and access your machine through Node.js APIs, script execution is disabled; furthermore, external resources (scripts, images, stylesheets, iframes) are not fetched. Even with these precautions, be careful with what web pages you process with hred; when in doubt, inspect the page's source code beforehand.

Related projects

You might be interested in these:

  • pup was the original jq for HTML;
  • x-ray has the concept of including HTML attributes in the query string;
  • gdomqsx looks a bit like GraphQL, so maybe GraphQL for DOM can be a thing;
  • tq — another popular CLI tool for extracting data from HTML;
  • htmlq — like jq, but for HTML;
  • xidel supports a variety of query languages (CSS, XQuery, XPath, etc.);
  • wikipedia_ql — a query language for efficient data extraction from Wikipedia;
  • dbohdan/structured-text-tools maintains a comprehensive list of command-line tools for manipulating structured text data.

About

Reduce HTML and XML to JSON from the command line, using an expressive query language inspired by CSS selectors.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published