Scraping Marvel Comics

Posted on Mar 20, 2016

Contributed by Christopher Redino. He is currently in the NYC Data Science Academy 12 week full time Data Science Bootcamp program taking place between January 11th to April 1st, 2016. This post is based on his third class project – Web scraping (due on the 6th week of the program).


Comic book fans love showing off their knowledge of their hobby. Knowing which characters appeared in which issues, when certain meet ups and throw downs occurred; their familiarity with the extensive history of these characters reflects their passion for comics. Stated another way, comic book fans love data! Strong evidence of this is the extensive and thorough Marvel Database, a wiki that catalogs characters, teams, locations, events, and issues from Marvel Comics. The main continuity of stories that appear in Marvel comics has been in existence for over 75 years, and their stories contain thousands of characters, so there is a lot of data here, but with a short and simple Python script we can scrape this data and create some illustrative visualizations.


This project focuses on appearance data; in which issues do certain characters appear. This can be interesting for a few reasons. The total number of appearances acts as a proxy for the popularity of a character, the more popular a character is, the more issues they will appear in. More popularity means longer lasting solo runs, more appearances on teams, more cameos and team ups in other's comics, and if they are  really popular, additional solo titles. Appearance data can also tell us which characters have appeared together most frequently in Marvel's long history, and can tell us about the relative make up of teams and how these rosters have changed over the decades.

Getting the Data

Wikis tend to be very well organized, which makes web scraping substantially easier. We can reasonably expect the same information to appear in the same place on every page. The whole script is rather short and is shown here in its entirety. Ignoring team data for now, this short script is all we need.


The script begins by specify which characters I am interested in learning about. Here I just pick five of the more popular characters: Captain America, Spider-Man, Wolverine, Iron Man and Thor, but other characters can be added as well. The script will go through each character one at a time, but the procedure for each character is the same. Each character  has their own main page on the wiki, for example we have Spider-Man's page:


It has some stats, some personal info, and a brief bio of the character, but the part we are interested in is towards the bottom which has a variety of links related to the character.


The appearances link takes us to a separate page which lists links to issues where the character has appeared.


We want the script to save each of these issue links to a list, and then go to the next page of issue links for this character and repeat the process until all the pages are exhausted. This is easier than it sounds as looking at the source we see the html is very organized.


Once the script has the list of issue links, it goes to each of these pages where we can find the release date of that issue.

When the script is done running we are left with a csv file that for each row lists the issue title, the character that appears in it, and the date of its release. If two of the characters we are interested in both appear Fin the same issue, it will appear as two separate rows in the data.

Before moving on to the visualization results of this data, it should be specified what exactly we have scraped by running this script. You'll notice that when the characters are specified, for example for Spider-Man, it does not say "spider-man" in the URL, but rather, it says "Peter Parker" and further more for each character's URL you'll notice it says "Earth 616". This specifies two things: we are only considering the Spider-Man character that is Peter Parker, and we are only considering the main continuity of the comic books. For all five characters scraped here, and for many more popular comic book characters, it is very common for the for super hero mantle to passed on to other characters, either as a legacy, or at least temporarily. Peter Parker is not the only "Spider-Man" of the comics, and there have in fact been several others, Miles Morales (from another universe), Ben Reilly ( a clone of Peter Parker), Miguel O'Hara (from the future), and many others, but we are only considering the original or "classic" version of each character here. The designation "616" specifies the continuity of the story, meaning there are other appearances of Peter Parker in some stories which are not in a consistent storyline with those scraped here. For those unfamiliar with comics, this is like when a studio reboots a movie franchise. Bela Legosi and Christopher Lee both play the same character of Count Dracula, but there separate movies share no continuity with one another.


With the appearance data we can look at a few different things, as mentioned in the motivation. Since the Python Script outputs a csv, I can then open the data with any other software I want to do the visualization, and in this case, since this is really time series data, I chose to use the dygraphs library as implemented in R to make interactive plots of the appearances of characters over time. The interactive plots can be found here, and your invited to play with them.

The first plot shows appearances per month for the five characters, over the entire history of marvel comics. Captain America has a bit of a head start, originally appearing in the 1940's with Wolverine coming in the latest among these heavy hitters. As mentioned earlier, this is sort of a proxy for popularity, and onne may think that taking the total appearance count as a measure of popularity is flawed, since some characters are introduced so much earlier. I think this plot addresses this issues somewhat by showing that the overall trend of more titles being published in general greatly out weighs this. While Captain America did have over a 20 year head start on most other characters, there really weren't that many titles released back then, at least not compared to the rate of release today.


It is also interesting to look at this graph in terms of what other events happened at each of these dates, both within the continuity of the stories, and also with what has happening in the real world at the time. Deaths of comic book characters this popular do not actually reduce their monthly appearances, and each of these characters has experienced death in some form in their history. While death in comic books is more a temporary set back rather than a final ending, even while characters remain "dead" they will appear in stories via flash backs.  Outside of the continuity of stories in the comics, the release of related movies clearly coincides with an increase in appearances. Perhaps the best example in this plot is the surge in Iron Man's appearances following his 2008 movie, but other examples can be found.

With a bit of reshaping we can produce another plot from the same data. The data shows when characters appear in each issue, and also two characters or more can appear in the same issue, so with the right manipulations we can show a time line of each grouping of characters. The groupings themselves are categories, which duos, trios or quartets appeared in each issue, but dygraphs expects numerical data, so we simply assign a different numerical value to each different grouping. It would also be nice if the groupings were sorted by there size, that is, if duos and trios were visually separated in our plot, so that the numerical values we assigned to these groups had some categorical meaning. This can be achieved by considering the numerical value of the group as a binary number, with each bit being the presence or absence of each character. To sort these values by duo trio, etc, we can sort on the sum of bits. Furthermore, to prevent over plotting (drawing one point over another) we can stagger these values between characters, that is to say if Captain America and Iron Man appear in an issue together than those appearances should have simliar but not identical group ID numbers. The a screen shot of the resulting interactive plot is given below, but please check out the interactive plot at the link given above. The vertical axis just denotes the category of the groupings, so it is unimportant. The way the plot should be read is that if two dots appears close together vertically then those two characters had at least one appearance together in an issue on that date. The bottom five lines are solo appearances, so these are well spaced.  The band of double lines above the solo appearances are all the pairings that appeared at each date, and above this the trios, and so on, with the top band of five tight lines being those issue dates where all five characters appeared together.


There are actually quite a few patterns that can be extracted from this plot. Some combinations of characters are much more frequent, and some are much more rare. Some combinations become more frequent with time, and sometimes two characters will only appear together if a third character is present. A lot of this can be explained by team dynamics; the band of blue yellow gray shows the three long time Avengers, Cap, Iron Man and Thor have appeared together consistently without the other two until recently. Spider-Wolverine do eventually become Avengers, and there increased team ups over time can be seen.

The last two plots show membership in the Avengers over time. This required a slightly modified version of the Python script shown above, but the basic idea is the same. Instead of saving those issues and dates for which a character appears, it saves the issues and date for which the team the avengers appears, and if one or more of these five characters of interest appeared as an avenger in that issue that is also saved. The first of these team membership plots just shows a running total of appearances as an avenger over time, and we can see how Captain America has a little bit of a late start, (just a few issues) but quickly becomes the most active Avenger, with Spider-Man and Wolverine only joining much more recently.



The second team plot is showing the same information as the first, except instead of a running total of appearances it shows the percent the relative share of appearances as an avenger over time. Again  at first Iron Man and Thor both have 50% of all avengers appearances, (among the characters considered) but towards today Captain America has over a third, with Iron Man and Thor having less than a third each and Spidey and Wolverine having a small remainder.



A wiki cataloging such a long history of media, such as the Marvel Database is a very natural choice for a data set to be visualized as a time series, and while there are some interesting visualizations shown here, there are a lot of ways this could be expanded.  The inclusion of more characters and other teams is very straightforward  so let me know who you want to see in the comments! At the very least I think I should add the Hulk so I can put some green in these plots. The characters shown here are all amongst the most popular in Marvel's library, so it should not be surprising that their trends over time look largely the same. Looking at less popular characters could be interesting because we could see their rise and fall, and in some cases their resurgence.  It would also be very cool if I could implement the functionality to actually show the issue title with mouse over on these plots (perhaps not with dygraphs, but something similar).

About Author

Christopher Redino

The common thread through all of Christopher's endeavors is his love of problem solving, with his usual methods being analytical and computational in nature. Having learned coding at an early age, Christopher picks up new programming languages quickly...
View all posts by Christopher Redino >

Leave a Comment

Shruti Singhal August 22, 2019
This looks good. I have never done data scraping; just wanted to try something new and came across this. Thanks for sharing this.
bulgari bague prix replique January 3, 2018
Pautz should remain as VOLUNTEER park commissioner. OUr parks are one of the assets in our community. WE do need more citizens involved in our government. We should be ashamed of our lack of development. To have such petty infighting on our council is detrimental to us all. Come on people time to grow up and work on the real issues in our community. bulgari bague prix replique
imitation bracelet cartier September 18, 2016
cartierbraceletlove Why have I never considered pumpkin cornbread? This is awesome, Maegan! Can’t wait to try it. imitation bracelet cartier

View Posts by Categories

Our Recent Popular Posts

View Posts by Tags

#python #trainwithnycdsa 2019 2020 Revenue 3-points agriculture air quality airbnb airline alcohol Alex Baransky algorithm alumni Alumni Interview Alumni Reviews Alumni Spotlight alumni story Alumnus ames dataset ames housing dataset apartment rent API Application artist aws bank loans beautiful soup Best Bootcamp Best Data Science 2019 Best Data Science Bootcamp Best Data Science Bootcamp 2020 Best Ranked Big Data Book Launch Book-Signing bootcamp Bootcamp Alumni Bootcamp Prep boston safety Bundles cake recipe California Cancer Research capstone car price Career Career Day citibike classic cars classpass clustering Coding Course Demo Course Report covid 19 credit credit card crime frequency crops D3.js data data analysis Data Analyst data analytics data for tripadvisor reviews data science Data Science Academy Data Science Bootcamp Data science jobs Data Science Reviews Data Scientist Data Scientist Jobs data visualization database Deep Learning Demo Day Discount disney dplyr drug data e-commerce economy employee employee burnout employer networking environment feature engineering Finance Financial Data Science fitness studio Flask flight delay gbm Get Hired ggplot2 googleVis H20 Hadoop hallmark holiday movie happiness healthcare frauds higgs boson Hiring hiring partner events Hiring Partners hotels housing housing data housing predictions housing price hy-vee Income Industry Experts Injuries Instructor Blog Instructor Interview insurance italki Job Job Placement Jobs Jon Krohn JP Morgan Chase Kaggle Kickstarter las vegas airport lasso regression Lead Data Scienctist Lead Data Scientist leaflet league linear regression Logistic Regression machine learning Maps market matplotlib Medical Research Meet the team meetup methal health miami beach movie music Napoli NBA netflix Networking neural network Neural networks New Courses NHL nlp NYC NYC Data Science nyc data science academy NYC Open Data nyc property NYCDSA NYCDSA Alumni Online Online Bootcamp Online Training Open Data painter pandas Part-time performance phoenix pollutants Portfolio Development precision measurement prediction Prework Programming public safety PwC python Python Data Analysis python machine learning python scrapy python web scraping python webscraping Python Workshop R R Data Analysis R language R Programming R Shiny r studio R Visualization R Workshop R-bloggers random forest Ranking recommendation recommendation system regression Remote remote data science bootcamp Scrapy scrapy visualization seaborn seafood type Selenium sentiment analysis sentiment classification Shiny Shiny Dashboard Spark Special Special Summer Sports statistics streaming Student Interview Student Showcase SVM Switchup Tableau teachers team team performance TensorFlow Testimonial tf-idf Top Data Science Bootcamp Top manufacturing companies Transfers tweets twitter videos visualization wallstreet wallstreetbets web scraping Weekend Course What to expect whiskey whiskeyadvocate wildfire word cloud word2vec XGBoost yelp youtube trending ZORI