Skip to content

Instantly share code, notes, and snippets.

@zeroflag
Created November 2, 2024 21:50
Show Gist options
  • Save zeroflag/a238d9fe0560a7cd1d6013ce58a94030 to your computer and use it in GitHub Desktop.
Save zeroflag/a238d9fe0560a7cd1d6013ce58a94030 to your computer and use it in GitHub Desktop.
(in-package :cl-user)
;;(ql:quickload '(:dexador :plump))
(defpackage :stocks
(:use :cl)
(:import-from :dexador)
(:import-from :plump))
(in-package :stocks)
(defvar *cookie-jar* (cl-cookie:make-cookie-jar))
(defparameter ENDPOINT "https://finance.yahoo.com/quote")
(defparameter USER-AGENT "curl/7.88.1")
(defun build-url (base path)
(concatenate 'string base "/" path "/"))
(defun stock-url (ticker)
(build-url ENDPOINT ticker))
(defun price-tag? (elem ticker)
(and (typep elem 'plump-dom:element)
(string= "fin-streamer" (plump-dom:tag-name elem))
(string= "regularMarketPrice" (plump-dom:attribute elem "data-field"))
(string= ticker (plump-dom:attribute elem "data-symbol"))))
(defun scrape (body ticker)
(print body)
(let ((html (plump:parse body))
(price nil))
(plump:traverse
html
(lambda (e)
(setf price (plump-dom:attribute e "data-value")))
:test (lambda (elem) (price-tag? elem ticker)))
(when price
(read-from-string price))))
(defun fetch (url)
(let ((retry-request (dex:retry-request 3 :interval 2)))
(handler-bind ((dex:http-request-failed retry-request))
(dex:get url
;;:cookie-jar *cookie-jar*
:headers `(("User-Agent" . ,USER-AGENT)
("Accept" . "*/*"))
:verbose t))))
(defun price (ticker)
(handler-case
(scrape (fetch (stock-url ticker)) ticker)
(dex:http-request-failed (e)
(format *error-output*
"Error: ~D for ticker: ~s"
(dex:response-status e)
ticker))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment