Webscraper for www.coinmarketcap.com I built a webscraper to take all the historical data from CoinMarketCap.com. A site which records historical data for cryptocurrencies which unfortunately does not have a feature to download all of their data in one convenient file.

It works but it's somewhat slow and probably could be designed better. I'm self taught so I'd love some advice on how to improve the code's functionality, speed, and readability. Thanks a lot in advance. 

def scrape_coin_marketcap():
    print('Loading Packages...')
    from bs4 import BeautifulSoup
    import requests
    import pandas as pd

    print('Scraping links...')
    #Download HTML of links to historical CoinMarketCap data
    url = 'https://coinmarketcap.com/historical/'
    r  = requests.get(url)
    data = r.text
    soup = BeautifulSoup(data,'html.parser')

    #scrape a list of links to historical data
    raw_links = []
    for link in soup.find_all('a'):
        raw_links.append(link.get('href'))

    #Remove non-historical links
    historical_links = []
    for link in raw_links:
        if "201" in str(link):
            historical_links.append('https://coinmarketcap.com' + link)

    print('Scraping Data....')

    #Scrape historical data from each time period
    master_df = pd.DataFrame()
    num_links = len(historical_links)
    print(str(num_links) + " dates to be scraped...")
    for link in historical_links:
        try:
            res = requests.get(link)
            soup = BeautifulSoup(res.content, 'lxml')
            table = soup.find_all('table')[0]
            df = pd.read_html(str(table))[0]
            date = str(soup.find_all('h1')[0])[51:-5]
            df['date'] = date
            master_df = master_df.append(df)
            print("    Scraping: " + str(date))
        except:
            print("    ERROR Scraping: " + str(link))

    print('Saving to disk...')
    master_df.to_csv('CoinMarketCap.csv', index = False)
    print("Completed.")

if __name__ == "__main__":
    scrape_coin_marketcap()
Welcome to Code Review SE, nice first question! Here are some of my comments, not pertaining to performance:


There's no reason to import modules in the body of scrape_coin_marketcap(). Just do it at the top of the source code file. If you need to be sure the modules are present at all, you can catch ImportError:

import sys

try:
    from bs4 import BeautifulSoup
    import requests
    import pandas as pd
except ImportError:
    sys.exit("This script requires Beautiful Soup 4, Requests and Pandas.")


Note: I'm using sys.exit() here instead of print(), because I'm assuming this is a standalone script and an ImportError should therefore be fatal.
The URL for the webpage is unlikely to change in the future, and isn't supposed to be modified at runtime, so you should mark it as a constant variable. Constants use the UPPERCASE_WITH_UNDERSCORES naming convention:

HISTORICAL_DATA_URL = "https://coinmarketcap.com/historical/"

This comment:

#Download HTML of links to historical CoinMarketCap data


... is pretty pointless. Anyone familiar with Python doesn't need that comment to understand what the snippet of code below it does. Only add comments to difficult to comprehend code, or to snippets that need extra attention for whatever reason.
The following pattern:

my_list = []
for x in some_iterable:
    my_list.append(some_function(x))


... is a good candidate for a list comprehension:

my_list = [some_function(x) for x in some_iterable]


... so in your case:

raw_links = [link.get("href") for link in soup.find_all("a")]


In fact, the part where you remove non-historical links could benefit from a list comprehension too:

historical_links = [
    "https://coinmarketcap.com/" + link for link in raw_links
    if "201" in str(link)
]

Don't mix single and double quotes. Either choice is valid, but mixing them is a bad idea. As an exception, you are encouraged to use single quotes if you need to output literal double quotes, and vice versa.
Unless you need access to the result of r.text later, don't bind it to a variable.
Debug / error messages should not be sent to stdout, but to stderr. You can do that by explicitly passing sys.stderr as a parameter to print():

import sys

...

print("Loading Packages...", file=sys.stderr)