{"id":13760846,"url":"https://github.com/charlespwd/hq","last_synced_at":"2025-03-17T01:29:25.595Z","repository":{"id":57104208,"uuid":"322057946","full_name":"charlespwd/hq","owner":"charlespwd","description":"jq's not so sophisticated cousin for HTML","archived":false,"fork":false,"pushed_at":"2020-12-16T19:15:15.000Z","size":6,"stargazers_count":7,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-19T09:02:57.092Z","etag":null,"topics":["html","jq"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/charlespwd.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-12-16T17:42:49.000Z","updated_at":"2024-02-24T12:01:25.000Z","dependencies_parsed_at":"2022-08-20T17:10:19.489Z","dependency_job_id":null,"html_url":"https://github.com/charlespwd/hq","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/charlespwd%2Fhq","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/charlespwd%2Fhq/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/charlespwd%2Fhq/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/charlespwd%2Fhq/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/charlespwd","download_url":"https://codeload.github.com/charlespwd/hq/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243957630,"owners_count":20374712,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["html","jq"],"created_at":"2024-08-03T13:01:24.050Z","updated_at":"2025-03-17T01:29:25.576Z","avatar_url":"https://github.com/charlespwd.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"# hq\n\n[`jq`](https://stedolan.github.io/jq/manual/)'s not as sophisticated cousin but for HTML.\n\n## Installation\n\n```\n# with npm\nnpm install -g @cpclermont/hq\n\n# with yarn\nyarn global add @cpclermont/hq\n```\n\n## Usage\n\nHTML isn't as well structured as JSON. But we can do some fun stuff with CSS selectors and attribute selectors.\n\n`hq` commands all start with a CSS selector and are then optionally passed into a transformation:\n\n```bash\n# example settings\nurl=\"https://www.webpagetest.org\"\ncssSelector=\"head \u003e script[src]:not([defer]):not([async])\"\n\n# examples\ncurl -s $url | hq \"$cssSelector\"\ncurl -s $url | hq \"$cssSelector | html\"\ncurl -s $url | hq \"$cssSelector | text\"\ncurl -s $url | hq \"$cssSelector | innerHTML\"\ncurl -s $url | hq \"$cssSelector | attr(src)\"\ncurl -s $url | hq \"$cssSelector | attr(src, href)\"\n```\n\n### Transformations\n\n* `html` (alias: `outerHTML`) returns the `outerHTML` of the node.\n* `text` returns the text in the node.\n* `innerHTML` returns the innerHTML of the node :grimacing:.\n* `attr(attrs)` returns the values of the attributes(comma separated).\n  The output of unmatched attributes is skipped, every attribute is output to a new line.\n\n  This exists so you can scrape URLs from different node types that\n  might live in different attributes.\n\n  e.g.\n\n  ```bash\n  curl -s https://www.webpagetest.org | hq '\n    head \u003e script[src]:not([defer]):not([async]),\n    head \u003e link[rel=stylesheet]\n    | attr(src, href)'\n  ```\n\n  Where we want to list render blocking scripts and stylesheets in the\n  order they are found.\n\n## Examples\n\n```\n# Get URLs of scripts that are render blocking\ncurl -s https://www.webpagetest.org | hq '\n  head \u003e script[src]:not([defer]):not([async])\n  | attr(src)'\n\n# Get URLs of scripts and stylesheets that are render blocking\ncurl -s https://www.webpagetest.org | hq '\n  head \u003e script[src]:not([defer]):not([async]),\n  head \u003e link[rel=stylesheet]\n  | attr(src, href)'\n```\n\n## Notes\n\nThis is scrappy and nowhere near as good as jq. But it's better than nothing :)\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcharlespwd%2Fhq","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcharlespwd%2Fhq","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcharlespwd%2Fhq/lists"}