HackerReposA FIELD GUIDE TO OPEN SOURCE
ProSponsor the shelf♧ 0
← Back to top all-time
ericchiang
pup
HTML2014–2024
ericchiang / pup

pup

Parsing HTML at the command line

27Distinct people
34Mentions
0Explicit recommenders
8.4KGitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

Parsing HTML at the command line

GitHub

Where it is used

No documented product use was verified in the last source check.

What people are saying

No recommendation phrase was found in the indexed comments.

No classified warning is attached to this page. Read the discussions before treating silence as approval.

Also in these discussions

No other repository is repeatedly linked in the same discussions.

This week on Hacker News

Nov 8–Nov 15 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/15/2026, 7:02:26 AM UTC.

No direct repository links were found in the indexed HN discussions over the past seven days. Older discussions are available below.

Mentions over time

HN mentions by year34 dated mentions

Observed mentions: 2014-09-13 12:58:43 UTC to 2024-03-20 00:22:58 UTC.

02468102014-01-01 00:00:00 UTC to 2015-01-01 00:00:00 UTC (exclusive): 2 mentions; 1 submissions, 1 comments20142015-01-01 00:00:00 UTC to 2016-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2016-01-01 00:00:00 UTC to 2017-01-01 00:00:00 UTC (exclusive): 2 mentions; 1 submissions, 1 comments2017-01-01 00:00:00 UTC to 2018-01-01 00:00:00 UTC (exclusive): 4 mentions; 1 submissions, 3 comments2018-01-01 00:00:00 UTC to 2019-01-01 00:00:00 UTC (exclusive): 3 mentions; 2 submissions, 1 comments2019-01-01 00:00:00 UTC to 2020-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments20192020-01-01 00:00:00 UTC to 2021-01-01 00:00:00 UTC (exclusive): 5 mentions; 2 submissions, 3 comments2021-01-01 00:00:00 UTC to 2022-01-01 00:00:00 UTC (exclusive): 7 mentions; 4 submissions, 3 comments2022-01-01 00:00:00 UTC to 2023-01-01 00:00:00 UTC (exclusive): 9 mentions; 2 submissions, 7 comments2023-01-01 00:00:00 UTC to 2024-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2024-01-01 00:00:00 UTC to 2025-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2024

Counts come from the repository’s dated source evidence. Index cutoff: 2026-11-02 08:16:59 UTC.

View mention counts and date ranges
UTC ranges include their start and exclude their end. Select a period to filter the source evidence.
PeriodStart (UTC)End (exclusive, UTC)MentionsSubmissionsComments
20142014-01-01 00:00:00 UTC2015-01-01 00:00:00 UTC211
20152015-01-01 00:00:00 UTC2016-01-01 00:00:00 UTC101
20162016-01-01 00:00:00 UTC2017-01-01 00:00:00 UTC211
20172017-01-01 00:00:00 UTC2018-01-01 00:00:00 UTC413
20182018-01-01 00:00:00 UTC2019-01-01 00:00:00 UTC321
20192019-01-01 00:00:00 UTC2020-01-01 00:00:00 UTC000
20202020-01-01 00:00:00 UTC2021-01-01 00:00:00 UTC523
20212021-01-01 00:00:00 UTC2022-01-01 00:00:00 UTC743
20222022-01-01 00:00:00 UTC2023-01-01 00:00:00 UTC927
20232023-01-01 00:00:00 UTC2024-01-01 00:00:00 UTC000
20242024-01-01 00:00:00 UTC2025-01-01 00:00:00 UTC101

From the project README

An excerpt from the repository, fetched Nov 13, 2026.

Read the project’s introduction
pup pup is a command line tool for processing HTML. It reads from stdin, prints to stdout, and allows the user to filter parts of the page using CSS selectors. Inspired by jq, pup aims to be a fast and flexible way of exploring HTML from the terminal. Install Direct downloads are available through the releases page. If you have Go installed on your computer just run go get. go get github.com/ericchiang/pup If you're on OS X, use Homebrew to install (no Go required). brew install https://raw.githubusercontent.com/EricChiang/pup/master/pup.rb Quick start $ curl -s https://news.ycombinator.com/ Ew, HTML. Let's run that through some pup selectors: $ curl -s https://news.ycombinator.com/ | pup 'table table tr:nth-last-of-type(n+2) td.title a' Okay, how about only the links? $ curl -s https://news.ycombinator.com/ | pup 'table table tr:nth-last-of-type(n+2) td.title a attr{href}' Even better, let's grab the titles too: $ curl -s https://news.ycombinator.com/ | pup 'table table tr:nth-last-of-type(n+2) td.title a json{}' Basic Usage $ cat index.html | pup [flags] '[selectors] [display function]' Examples Download a webpage with wget. $ wget http://en.wikipedia.org/wiki/Robots_exclusion_standard -O robots.html Clean and indent By default pup will fill in missing tags and properly indent the page. $ cat robots.html # nasty looking HTML $ cat robots.html | pup --color # cleaned, indented, and colorful HTML Filter by tag $ cat robots.html | pup 'title' <title> Robots exclusion standard - Wikipedia, the free encyclopedia </title> Filter by id $ cat robots.html | pup 'span#See_also' <span class="mw-headline" id="See_also"> See also </span> Filter by attribute $ cat robots.html | pup 'th[scope="row"]' <th scope="row" class="navbox-group"> Exclusion standards </th> <th scope="row" class="navbox-group"> Related marketing topics </th> <th scope="row" class="navbox-group"> Search marketing related topics </th> <th scope="row" class="navbox-group"> Search engine spam </th> <th scope="row" class="navbox-group"> Linking </th> <th scope="row" class="navbox-group"> People </th> <th scope="row" class="navbox-group"> Other </th> Pseudo Classes CSS selectors have a group of specifiers called "pseudo classes" which are pretty cool. pup implements a majority of the relevant ones them. Here are some examples. $ cat robots.html | pup 'a[rel]:empty' <a rel="license" href="//creativecommons.org/licenses/by-sa/3.0/" style="display:none;"> </a> $ cat robots.html | pup ':contains("History")' <span class="toctext"> History </span> <span class="mw-headline" id="History"> History </span> $ cat robots.html | pup ':parent-of([action="edit"])' <span class="wb-langlinks-edit wb-langlinks-link"> <a action="edit" href="//www.wikidata.org/wiki/Q80776#sitelinks-wikipedia" text="Edit links" title="Edit interlanguage links" class="wbc-editpage"> Edit links </a> </span> For a complete list, view the implemented selectors section. +, >, and , These are intermediate characters that declare special instructions. For instance, a comma , allows pup to specify multiple groups of selectors. $ cat robots.html | pup 'title, h1 span[dir="auto"]' <title> Robots exclusion standard - Wikipedia, the free encyclopedia </title> <span dir="auto"> Robots exclusion standard </span> Chain selectors together When combining selectors, the HTML nodes selected by the previous selector will be passed to the next ones. $ cat robots.html | pup 'h1#firstHeading' <h1 id="firstHeading" class="firstHeading" lang="en"> <span dir="auto"> Robots exclusion standard </span> </h1> $ cat robots.html | pup 'h1#firstHeading span' <span dir="auto"> Robots exclusion standard </span> Implemented Selectors For further examples of these selectors head over to MDN. pup '.class' pup '#id' pup 'element' pup 'selector + selector' pup 'selector > selector' pup '[attribute]' pup '[attribute="value"]' pup '[attribute*="value"]' pup '[attribute~="value"]' pup '[attribute^="value"]' pup '[attribute$="value"]' pup ':empty' pup ':first-child' pup ':first-of-type' pup ':last-child' pup ':last-of-type' pup ':only-child' pup ':only-of-type' pup ':contains("text")' pup ':nth-child(n)' pup ':nth-of-type(n)' pup ':nth-last-child(n)' pup ':nth-last-of-type(n)' pup ':not(selector)' pup ':parent-of(selector)' You can mix and match selectors as you wish. cat index.html | pup 'element#id[attribute="value"]:first-of-type' Display Functions Non-HTML selectors which effect the output type are implemented as functions which can be provided as a final argument. text{} Print all text from selected nodes and children in depth first order. $ cat robots.html | pup '.mw-headline text{}' History About the standard Disadvantages Alternatives Examples Nonstandard extensions Crawl-delay directive Allow directive Sitemap Host Universal "*" match Meta tags and headers See also References External links attr{attrkey} Print the values of all attributes with a given key from all selected nodes. $ cat robots.html | pup '.catlinks div attr{id}' mw-normal-catlinks mw-hidden-catlinks json{} Print HTML as JSON. $ cat robots.html | pup 'div#p-namespaces a' <a href="/wiki/Robots_exclusion_standard" title="View the content page [c]" accesskey="c"> Article </a> <a href="/wiki/Talk:Robots_exclusion_standard" title="Discussion about the content page [t]" accesskey="t"> Talk </a> $ cat robots.html | pup 'div#p-namespaces a json{}' [ { "accesskey": "c", "href": "/wiki/Robots_exclusion_standard", "tag": "a", "text": "Article", "title": "View the content page [c]" }, { "accesskey": "t", "href": "/wiki/Talk:Robots_exclusion_standard", "tag": "a", "text": "Talk", "title": "Discussion about the content page [t]" } ] Use the -i / --indent flag to control the intent level. $ cat robots.html | pup -i 4 'div#p-namespaces a json{}' [ { "accesskey": "c", "href": "/wiki/Robots_exclusion_standard", "tag": "a", "text": "Article", "title": "View the con
Read the full README on GitHub

What Hacker News says

2 sources

MAKE YOURSELF AT HOME

A few shortcuts

/
Search the collection
?
Open this guide
Esc
Close dialogs and navigation

Your saved repositories and interests stay in this browser.