Alex Preston / blog

Script for Book Notes

Mon Jul 31 2023

I created a script to send me quotes from books I read, similar to Readwise, but free!

I have all my book notes already on this blog so the script was fairly easy to put together.

I just use HTTP requests to get the full list of books and then parse the HTML to get a few titles and links to their highlight pages.

I do a bit of validation since not every book has its own page of highlights. However if the book does have a page I make a request and randomly grab some highlights.

The script then combines all these highlights into an email and sends it to me twice daily.

This script is pretty easy to put together, but its worth noting all this only really works if your notes are organized the same way. I had to reformat a of the book highlight pages since bs4 couldn't parse some of the pages properly.

import requests
from bs4 import BeautifulSoup
import random
import os
from sendgrid import SendGridAPIClient
from sendgrid.helpers.mail import Mail

def getRandomBooks(numOfBooks):
    urlToBookNotes = ""
    response = requests.get(urlToBookNotes)
    html_content = response.text
    soup = BeautifulSoup(html_content, 'html.parser')
    a_tags = soup.find_all('a')
    filtered_a_tags = [tag for tag in a_tags if tag.get('href') != "/"]
    return random.sample(filtered_a_tags, numOfBooks)

def getRandomHighlights(randomBooks, numHighlightsPerBook):
    highlights = {}
    for book in randomBooks:
        url = "" + book.get('href')
        response = requests.get(url)
        html_content = response.text
        soup = BeautifulSoup(html_content, 'html.parser')
        li_tags = soup.find_all('li')
            sampledHighlights = random.sample(li_tags, numHighlightsPerBook)
            highlights[book.text] = [highlight.text.strip() for highlight in sampledHighlights]
            print("Couldn't grab highlights for", book.text)
    return highlights

def sendHighlights(highlights):
    textBody = ""
    for book in highlights.keys():
        textBody += "<p><u><b>" + book + "</b></u></p>"
        for highlight in highlights[book]:
            textBody += "<ul><li>" + highlight + "</li></ul>"

    message = Mail(
        subject='Book Notes',

        key = os.environ.get('SENDGRID_API_KEY')
        sg = SendGridAPIClient(key)
        response = sg.send(message)
    except Exception as e:

def getHighlights():
    randomBooks = getRandomBooks(5)
    randomHighLights = getRandomHighlights(randomBooks, 1)