Reputation: 3959
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.
Upvotes: 3
Views: 320
Reputation: 14730
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 username
got 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))
Upvotes: 2
Reputation: 11839
The parameters
argument to drakma:http-request
is quoted, so it's not getting the strings you passed in the alist, it's getting the symbols USERNAME
and PASSWORD
. You need to construct the list in such a way that it includes the argument variables in a context where they're evaluated, e.g. (list (cons "username" username) (cons "password" password))
.
Upvotes: 1