Emacs: HTML. Extract URL 📜

By Xah Lee. Date: . Last updated: .

Here's a command to extract all URLs in a HTML file.

put this in your Emacs Init File:

(defun xah-html-extract-url (zbegin zend &optional zrootdir zfullpath-p zinteract-p)
  "Extract URLs in current block or selection to `kill-ring'.

When called interactively, copy result to `kill-ring', each URL in a line.
If the URL is a local file relative path, convert it to full path.

If `universal-argument' is called first, don't convert relative URL to full path.

This command extracts all text of the forms
 <a … href=path>
 <link … href=path>
 <img … src=path …>
 <script … src=path …>
 <video … src=path …>

Warning: path must be \"QUOTATION MARK\" quoted.
APOSTROPHE or unquoted attribute value is not supported.

When called in lisp code,
• zbegin zend are region begin/end positions.
• zrootdir is a dir path. relative paths are computed from.
• Optional zfullpath-p, if true, convert local links to full path, with respect to zrootdir.
• zinteract-p if true, copy to kill-ring as text and print it to message buffer.
• Returns a list of strings.

URL `http://xahlee.info/emacs/emacs/elisp_extract_url_command.html'
Created: 2021-02-20
Version: 2025-07-14"
  (interactive
   (let (xbeg xend)
     (seq-setq (xbeg xend) (if (region-active-p) (list (region-beginning) (region-end)) (list (save-excursion (if (re-search-backward "\n[ \t]*\n" nil 1) (match-end 0) (point))) (save-excursion (if (re-search-forward "\n[ \t]*\n" nil 1) (match-beginning 0) (point))))))
     (list xbeg xend default-directory (not current-prefix-arg) :interact-p)))
  (let (xurlList xresult)
    (save-excursion
      (save-restriction
        (narrow-to-region zbegin zend)
        (goto-char (point-min))
        (while (re-search-forward
                "\\(?:<a[ \n]+[^<>]*?href[ \n]*?=[ \n]*?\"\\(?8:[^\"]+\\)\"\\)\\|\\(?:<link[ \n]+[^<>]*?href[ \n]*?=[ \n]*?\"\\(?8:[^\"]+\\)\"\\)\\|\\(?:<img[ \n]+[^<>]*?src[ \n]*?=[ \n]*?\"\\(?8:[^\"]+\\)\"\\)\\|\\(?:<script[ \n]+[^<>]*?src[ \n]*?=[ \n]*?\"\\(?8:[^\"]+\\)\"\\)\\|\\(?:<video[ \n]+[^<>]*?src[ \n]*?=[ \n]*?\"\\(?8:[^\"]+\\)\"\\)"
                nil t)
          (push (match-string-no-properties 8) xurlList))
        (setq xresult
              (reverse
               (if zfullpath-p
                   (let ((xparendir (or buffer-file-name (or zrootdir default-directory))))
                     (mapcar
                      (lambda (xx)
                        (if (string-match "\\`http:\\|\\`https:" xx)
                            xx
                          (expand-file-name (string-remove-prefix "file:///" xx) (file-name-directory xparendir))))
                      xurlList))
                 xurlList)))))
    (when zinteract-p
      (let ((xprintStr (mapconcat 'identity xresult "\n")))
        (kill-new xprintStr)
        (message "%s" xprintStr)))
    xresult))

this is part of Emacs: Xah HTML Mode 📦.