Dyota's blog

JavaScript: AI-generated bookmarklet, code and thoughts

I've been avoiding using AI for a while now, but this one time, I didn't have the time or the expertise available to me, so I reached for a LLM.

I needed to scrape something off a web page, but as is typical these days, the website is a JavaScript-fueled labyrinth of nested tags, odd class names, and HTML that is hard to read. In the past, I would have bashed through and did rounds upon rounds of trial and error until I got the result I wanted, but I didn't have the time this time. I also had not touched JavaScript is probably a year.

What I wanted to do was to compose some JavaScript into a bookmarklet that I can click to scrape the HTMl, compose a handy table, and put it into my system clipboard.

I had heard that Claude is good for coding, so I went on and gave it a shot. I told it what I wanted to do, fed it the entire HTML page, and iterated with it until I got to my final solution.

It turns out that I had just enough free messages to arrive at a solution!

Some notes, mostly to justify to myself that my knowledge is not redudant:

Anyway, this is the code that Claude made for me. In the real bookmarklet, all this code is all together in one line, no spaces.

javascript:(
    function(){
        function parseCompetitionResults(){
            let csvOutput = 'Place,Name,Club,Event\r\n';
            document
                .querySelectorAll('.result')
                .forEach( division  =>  {
                    const eventElement = division.querySelector('h2');
                    const event = eventElement ? eventElement.textContent.trim().replace(/\s*<!---->\s*$/,'') : 'Unknown Event';
                    division
                        .querySelectorAll('.clearfix')
                        .forEach( row => {
                            const placeElement = row.querySelector('.place');
                            const place = placeElement ? placeElement.textContent.trim() : '';
                            const nameElement = row.querySelector('.name a')||row.querySelector('.name div');
                            const name = nameElement ? nameElement.textContent.trim().replace(/\s*\n.*$/,'').replace(/,/g,'') : '';
                            const clubElement = row.querySelector('.club');
                            const club = clubElement ? clubElement.textContent.trim().replace(/,/g,'') : '';
                            if(place&&name&&club){csvOutput+ = `${place},${name},${club},${event}\r\n`}
                        } )
                } );
            const tempTextArea = document.createElement('textarea');
            tempTextArea.value = csvOutput;
            document.body.appendChild(tempTextArea);
            tempTextArea.select();
            try{
                if(navigator.clipboard){
                    navigator.clipboard.writeText(csvOutput).then(() => {alert('Competition results copied to clipboard!')}).catch(err => {document.execCommand('copy');
                        alert('Competition results copied to clipboard!')})
                } else {
                    document.execCommand('copy');
                    alert('Competition results copied to clipboard!')
                };
            }
            catch (err) {
                alert('Failed to copy results to clipboard');
            }
            finally{
                document.body.removeChild(tempTextArea)
            }
        }
        
        parseCompetitionResults()
    }
)();

#ai #bookmarklet #javascript