As part of my ongoing quest to learn AI, I recently joined Kaggle, the Google-owned machine learning competition site. While I’m nowhere near ready to enter the contests hosted on there, I thought I might contribute an original dataset for other coders to use.

The question was, what kind of data to gather and compile? I knew I didn’t want to make another hotel bookings dataset as those have already been done to death. I thought of doing something related to trilobites, or exoplanets, but ultimately decided to start simpler.

The Internet Speculative Fiction Database is a project that aims to catalog every published literary work in the science fiction and fantasy genres. From what I can tell, they’ve basically succeeded in that task. As someone drawn more to the possible than the actual, I’ve been a science fiction fan all my life, and making a Kaggle dataset from ISFDB data seemed like a great idea.

Unfortunately, ISFDB doesnt provide a convenient API to get the data, so I knew I’d have to write a script to scrape what I needed from the website. Seeing as the site has an unfamiliar cataloging scheme, in addition to the fact that it’s been gradually added to since 1995, I knew this wasn’t going to be a pleasant process. Indeed, the final dataset I ended up with is fairly basic. Just book title, author, publication date, and type (e.g. novel, short story, anthology etc.)

Several entries had interesting possible data categories such as thematic tags (e.g. lost colony), but as only some of the titles had these, including them in the final dataset would have led to a ton of missing values.

 

Below is the script I wrote to scrape the site and build the dataset. After completion, you’ll have a CSV file with the metadata of about 125,000 books. It takes several hours to run on a basic Linux server:

 

temp.py

   1 
   
   2 
    import requests
   3 
    import bs4
   4 
    import clevercsv
   5 
    import re
   6 
 
   7 
 
   8 
 
   9 
 
  10 
    def catalog():
  11 
       
  12 
        """
  13 
        Scrapes metadata of science fiction and fantasy literary works
  14 
        from The Internet Speculative Fiction Database and stores them in
  15 
        a CSV file. If site structure changes significantly, code may stop
  16 
        functioning properly.
  17 
       
  18 
        """
  19 
 
  20 
        card = 0
  21 
       
  22 
        for entry in range(199000):
  23 
           
  24 
            try:
  25 
           
  26 
                card += 1
  27 
 
  28 
               
  29 
                page = requests.get(
  30 
                    f"http://www.isfdb.org/cgi-bin/title.cgi?{card}")
  31 
                parsed = bs4.BeautifulSoup(
  32 
                    page.content,
  33 
                    "html.parser")
  34 
                content = parsed.find(
  35 
                    id = "content").text.split("\n")
  36 
                content_string = "##".join(content)
  37 
 
  38 
               
  39 
                content_title = re.search(
  40 
                    "Title:\\s+[^#]+", content_string).group(0)
  41 
                title = content_title.split(": ")[1]
  42 
 
  43 
                content_author = re.search(
  44 
                    "Author:##[^#]+", content_string).group(0)
  45 
                author = content_author.split("##")[1]
  46 
 
  47 
                content_date = re.search(
  48 
                    "Date:\\s+\\d+\\-\\d+\\-\\d+", content_string).group(0)
  49 
                pubdate = content_date.split("  ")[1]
  50 
 
  51 
                content_type = re.search(
  52 
                    "Type:\\s+[^#]+", content_string).group(0)
  53 
                booktype = content_type.split(": ")[1]
  54 
 
  55 
 
  56 
                accepted_booktype = [
  57 
                    "NOVEL", 
  58 
                    "SHORTFICTION",
  59 
                    "COLLECTION",
  60 
                    "ANTHOLOGY",
  61 
                    "OMNIBUS",
  62 
                    "POEM",
  63 
                    "NONFICTION",
  64 
                    "ESSAY"]
  65 
 
  66 
 
  67 
                with open(
  68 
                    "SFF_Dataset.csv", "a", encoding="UTF-8") as sff:
  69 
                    dataset = clevercsv.writer(sff)
  70 
 
  71 
                    if sff.tell() == 0:
  72 
                       
  73 
                        dataset.writerow(
  74 
                            ["Title",
  75 
                            "Author",
  76 
                            "Publication Date",
  77 
                            "Type"])
  78 
 
  79 
                    if booktype in accepted_booktype:
  80 
 
  81 
                        dataset.writerow(
  82 
                            [title,
  83 
                            author,
  84 
                            pubdate,
  85 
                            booktype])
  86 
 
  87 
 
  88 
            except:
  89 
 
  90 
                print(
  91 
                    f"Skipping entry no. {card}: Empty article.", "\n" *4)
  92 
 
  93 
                continue 
  94 
 
  95 
 
  96 
 
  97 
    if __name__ == "__main__":
  98 
 
  99 
        catalog()
 100 
 
 101 
 
 102 
 
 103 
 
 104 
       

 

Below is how the dataset looks in Calc from LibreOffice:

 

Dataset

 

Full code repo available on Github

 

Update: I’ve coded a Reddit bot that uses the dataset. It watches for comments containing mentions of books in the dataset, than searches YouTube for audiobook versions of the mentioned book.

 

Related posts:

Speculative Fiction Bot

EXP-RTL: Exponential Retaliation In Iterated Prisoner’s Dilemma Games

Square Neighborhood Algorithm: Balancing Exploration And Exploitation In Optimization

Interleaved Neighborhood Algorithm: Fully Exploratory Optimization

 

About Me