I have a function which uses Drakma to GET a web page:
(defun scrape ()
(let ((cookie-jar (make-instance 'drakma:cookie-jar)))
(drakma:http-request "http://www.example.com/account/login"
:method :post
:parameters '(("username" . "myusername")
("password" . "mypassword"))
:cookie-jar cookie-jar)
(setq body (drakma:http-request "http://www.example.com/"
:cookie-jar cookie-jar))
(format t body)))
This works just as I expect. However, if I parameterise the username and password like so:
(defun scrape (username password)
(let ((cookie-jar (make-instance 'drakma:cookie-jar)))
(drakma:http-request "http://www.example.com/account/login"
:method :post
:parameters '(("username" . username)
("password" . password))
:cookie-jar cookie-jar)
(setq body (drakma:http-request "http://www.example.com/"
:cookie-jar cookie-jar))
(format t body)))
… and invoke it like so:
(scrape "my_username" "my_password")
… then I get the following error:
*** - Don't know what to do with name/value pair ("username" . USERNAME) in multipart/form-data body.
I’m new to Lisp, so I’m 100% certain that I’m missing something very straightforward to do with parameters here. E.g. if I add a call to format to the scrape function I can see that the username is being passed through correctly.
When you use quotation to create a literal list, the quotation extends down to inhibit evaluation of all the members of the list. You can see how
usernamegot upcased by the time it got printed out, which is the default for reading symbols.You have to build up the list structure using LIST and CONS forms as necessary, or use the backquote which allows you to selectively evaluate pieces, i.e.
(list (cons "username" username) (cons "password" password))or
`(("username" . ,username) ("password" . ,password))