<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Newspaper3k Archives - Be on the Right Side of Change</title>
	<atom:link href="https://blog.finxter.com/category/newspaper3k/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.finxter.com/category/newspaper3k/</link>
	<description></description>
	<lastBuildDate>Sat, 11 Sep 2021 16:15:08 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://blog.finxter.com/wp-content/uploads/2020/08/cropped-cropped-finxter_nobackground-32x32.png</url>
	<title>Newspaper3k Archives - Be on the Right Side of Change</title>
	<link>https://blog.finxter.com/category/newspaper3k/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Analyzing News Articles with Newspaper3k, TextBlob, and Seaborn</title>
		<link>https://blog.finxter.com/analyzing-news-articles-with-newspaper3k-textblob-and-seaborn/</link>
		
		<dc:creator><![CDATA[Craig Helstowski]]></dc:creator>
		<pubDate>Sat, 11 Sep 2021 12:42:59 +0000</pubDate>
				<category><![CDATA[Data Science]]></category>
		<category><![CDATA[Data Visualization]]></category>
		<category><![CDATA[Newspaper3k]]></category>
		<guid isPermaLink="false">https://blog.finxter.com/?p=35052</guid>

					<description><![CDATA[<p>In this final installment of my series on Newspaper3k, we will see the real possibilities of what we can do after scraping massive amounts of news articles.  To demonstrate data will be collected from 3 popular American news websites for a full year, from September of 2020 to August of 2021.  We will analyze articles ... <a title="Analyzing News Articles with Newspaper3k, TextBlob, and Seaborn" class="read-more" href="https://blog.finxter.com/analyzing-news-articles-with-newspaper3k-textblob-and-seaborn/" aria-label="Read more about Analyzing News Articles with Newspaper3k, TextBlob, and Seaborn">Read more</a></p>
<p>The post <a href="https://blog.finxter.com/analyzing-news-articles-with-newspaper3k-textblob-and-seaborn/">Analyzing News Articles with Newspaper3k, TextBlob, and Seaborn</a> appeared first on <a href="https://blog.finxter.com">Be on the Right Side of Change</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>In this final installment of my series on <a href="https://blog.finxter.com/newspaper3k-a-python-library-for-fast-web-scraping/" target="_blank" rel="noreferrer noopener">Newspaper3k</a>, we will see the real possibilities of what we can do after scraping massive amounts of news articles.  To demonstrate data will be collected from 3 popular American news websites for a full year, from September of 2020 to August of 2021.  We will analyze articles about current US President Joe Biden and find out what we can learn from the charts.</p>



<p>We will do some basic web scraping with the help of <a href="https://blog.finxter.com/web-scraping-with-beautifulsoup-in-python/" target="_blank" rel="noreferrer noopener">BeautifulSoup</a> and <a href="https://blog.finxter.com/category/newspaper3k/" target="_blank" rel="noreferrer noopener" title="https://blog.finxter.com/category/newspaper3k/">Newspaper3k</a>.  Then we will use <code>TextBlob</code> to do some sentiment analysis, store the data in a <a href="https://blog.finxter.com/pandas-to_csv/" target="_blank" rel="noreferrer noopener" title="Pandas to_csv()">CSV </a>file, and finally plot the data using pandas <em><a href="https://blog.finxter.com/how-to-create-a-dataframe-in-pandas/" target="_blank" rel="noreferrer noopener" title="How to Create a DataFrame in Pandas?">DataFrames</a></em> and <em><a href="https://blog.finxter.com/heatmaps-with-seaborn/" target="_blank" rel="noreferrer noopener" title="Creating Beautiful Heatmaps with Seaborn">Seaborn</a></em>.</p>



<p>I will also show you a cool trick that can allow you to get a massive amount of articles if you know precisely want you need to look for.&nbsp; Hint: Google doesn’t put requests limits on ALL pages on their site. <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p>I have all of my code (<code>BidenProject.ipynb</code>) and a CSV file (<code>combined.csv</code>) of the article data on <a href="https://github.com/finxter/Articles" target="_blank" rel="noreferrer noopener" title="https://github.com/finxter/Articles">my Github page</a>.  Otherwise, let’s jump right in.</p>



<p><strong>Video</strong>: As you go through the article, you can also watch my explainer video presenting the code snippets and more introduced here—in an easy-to-follow, step-by-step manner:</p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe title="Analyzing News Articles with Newspaper3k, TextBlob, and Seaborn" width="937" height="527" src="https://www.youtube.com/embed/OH5bW5g-CwQ?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<h2 class="wp-block-heading">A Quick Word About Google News RSS Feeds</h2>



<p>I’m personally a big fan of scraping RSS feeds because they allow me to continually scrape up-to-date news.&nbsp; In our case, however, we are looking to scrape much older data, and finding archived online news articles can be a bit of a hassle.&nbsp; In this case, we are lucky enough to have Google News help us.</p>



<p>If you do not know, if you are doing a Google News search you can receive your results in the form of an RSS feed by going to the URL and replacing <em>‘news.google.com/’</em> with <em>‘news.google.com/rss/’.</em>  Depending on several factors you can pull news articles older than 10 years.  I can do a search for Barack Obama on <a href="https://cnn.com" target="_blank" rel="noreferrer noopener" title="https://cnn.com">CNN.com</a> from 2008 and I get about 60 hits, assuming all of these articles have Obama included.</p>



<p>Even though Google puts a limit on your access, they seem to allow their RSS feeds to be accessed freely.&nbsp; In other words, there are no requests limits to their feeds, so you can scrape them as much as you want.&nbsp; We can now use Google to do the heavy lifting and find articles for us.&nbsp; All we need to do is scrape the links and code the data analysis.</p>



<p>Unfortunately, <em>Google News RSS</em> feeds will give you a maximum of 100 articles.  Therefore, if you know your search is going to have over 100 results, you may need to fiddle around with the parameters and adjust the number of RSS feeds to scrape.  There is a good resource <a href="https://blog.newscatcherapi.com/google-news-rss/" target="_blank" rel="noreferrer noopener">here</a> as well if you are interested to learn more about Google News RSS feeds.</p>



<h2 class="wp-block-heading">Scraping the Articles with Newspaper3k and Producing Sentiment Scores with TextBlob</h2>



<p>As mentioned above, we are going to scrape articles about President Biden from the following news services: ABC News, CNN, and Fox News.&nbsp; We will collect 100 articles per month from September 2020 to August 2021, do a sentiment analysis of each article, save the data, and then plot monthly data and do some basic analysis.</p>



<p>Before we begin, if this is your first introduction to Newspaper3k and text sentiment analysis, I have written articles <a href="https://blog.finxter.com/newspaper3k-a-python-library-for-fast-web-scraping/">h</a><a href="https://blog.finxter.com/newspaper3k-a-python-library-for-fast-web-scraping/" target="_blank" rel="noreferrer noopener">e</a><a href="https://blog.finxter.com/newspaper3k-a-python-library-for-fast-web-scraping/">re</a> and <a href="https://blog.finxter.com/how-to-generate-a-word-cloud-with-newspaper3k-and-python/" target="_blank" rel="noreferrer noopener">here</a> introducing the subject.  Therefore, I will not go over the scraping part in great detail.  Instead, I will show you the code and briefly review it.  You can type it out in either your <a href="https://blog.finxter.com/python-idle-vs-pycharm/" target="_blank" rel="noreferrer noopener" title="Python IDLE vs PyCharm">preferred code editor</a> or <a href="https://blog.finxter.com/category/jupyter/" target="_blank" rel="noreferrer noopener">Jupyter Notebooks</a> however, I used Jupyter to do the entire code for this exercise. </p>



<p>First, we import the necessary libraries:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import requests
from newspaper import Article, ArticleException
from bs4 import BeautifulSoup
from dateutil.rrule import *
from datetime import *
from textblob import TextBlob
import nltk
import csv

nltk.download('punkt')
</pre>



<p>Now, we need to set our timeframe.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">start_dates = [datetime.strftime(dt, "%Y-%m-%d") for dt in rrule(MONTHLY, dtstart=datetime(2020, 9, 1), until=datetime(2021, 8, 1))]
end_dates = [datetime.strftime(dt, "%Y-%m-%d") for dt in rrule(MONTHLY, dtstart=datetime(2020, 9, 30), bymonthday=(31, -1), bysetpos=1, until=datetime(2021, 8, 31))]
dates_list = list(zip(start_dates, end_dates))</pre>



<p>I’m using the <a href="https://blog.finxter.com/dealing-with-timezone-differences-in-python/" target="_blank" rel="noreferrer noopener" title="How to Handle Timezone Differences in Python"><em>dateutil</em> </a>library to set our dates for us.  <em><code>datetime.rrule</code></em> allows us to efficiently set our monthly intervals and get the correct number of days per month.  Using <a href="https://blog.finxter.com/list-comprehension/" target="_blank" rel="noreferrer noopener" title="List Comprehension in Python — A Helpful Illustrated Guide">list comprehension</a> we set a <a href="https://blog.finxter.com/python-lists/" target="_blank" rel="noreferrer noopener" title="The Ultimate Guide to Python Lists">list </a>of start dates and end dates for every month.  Then we use <a href="https://blog.finxter.com/zip-unzip-python/" target="_blank" rel="noreferrer noopener"><code>zip()</code></a> to pair the appropriate start and end dates together into tuples, and then put those pairs into a big list.  These will be the search terms for the start and end dates and we need them to be in the <code>'datetime'</code> format shown.</p>



<p>I will now show you the function which takes those dates as a parameter and then will scrape the articles and perform the sentiment analysis.  This section will take several hours to run.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">def get_articles(dates):
    news_sites = ['foxnews.com', 'cnn.com', 'abcnews.go.com']
    data = []

    for site in news_sites:
        
        # loop through each set of dates you wish to input
        for date1, date2 in dates:
            articles = []
            
            # URL of the Google News RSS with Joe Biden in the search parameter
            main_url = "https://news.google.com/rss/search?q=joe+biden+after:" + date1 + "+before:" + 
                date2 + "+site:" + site + "&amp;ceid=US:en&amp;hl=en-US&amp;gl=US"
            
            # get the results in the RSS and collect the links
            response = requests.get(main_url)
            webpage = response.content
            soup = BeautifulSoup(webpage, features="xml")
            items = soup.find_all('item')
            for item in items:
                link = item.find('link').text
                articles.append(link)

            # parse the articles and get the polarity and subjectivity scores for each in your 
            # specified time frame
            for url in articles:
                # print(url)
                # We throw this in a try/except block in case we get a bad link which would kill the program
                try:
	        # Newspaper3k to scrape the article text and title
                    article = Article(url)
                    article.download()
                    article.parse()
                    article.nlp()

                    title = article.title
                    text = article.text
                                        
                    # to make sure that the article does include Joe Biden
                    # depending on your criteria, Google will often give you completely irrelevant results
                    if 'Biden' in text:

                        # run sentiment analysis on the article text
                        # create a Textblob object and then get the sentiment values and store them
                        text_blob = TextBlob(text)
                        polarity = text_blob.polarity
                        subjectivity = text_blob.subjectivity

                        # in case we get a non-article as a link - do not include in data 
                        if polarity == 0 and subjectivity == 0:
                            pass
                        else:
                            # Save the necessary data to then put in a csv file
                            save = [site, url, title, datetime.strptime(date2, '%Y-%m-%d').strftime('%Y-%m'), polarity, subjectivity] 
                            data.append(save)
                
                # If there is a bad link, move on to the next one
                except ArticleException:
                    pass

    return(data)

# collect the article data with our specified dates
articles = get_articles(dates_list)

# write data to csv
with open('combined.csv', 'w') as csv_file:
    header = ['News Source', 'URL', 'Title', 'Month', 'Polarity', 'Subjectivity']
    writer = csv.writer(csv_file)
    writer.writerow(header)
    writer.writerows(articles)
    csv_file.close()
</pre>



<p>After passing the dates into <code>get_articles()</code> we collect an RSS feed for every month by putting in each start and end date, as well as the URL of the news source, as strings into the Google RSS URL string.  Then we store all of those articles from the feed into a list, scrape and do sentiment analysis on each article, and then save the data into a <a href="https://blog.finxter.com/how-to-read-a-csv-file-into-a-python-list/" target="_blank" rel="noreferrer noopener" title="How to Read a CSV File Into a Python List?">CSV </a>file we can store for later use.</p>



<p>It is necessary to put the scraping code in a try/except block in case there happens to be a bad article link in your results which would kill the program.  The exception given will be an ‘ArticleException’ error when running Newspaper3k, so use that in your ‘<a href="https://blog.finxter.com/how-to-catch-and-print-exception-messages-in-python/" target="_blank" rel="noreferrer noopener" title="How to Catch and Print Exception Messages in Python">except</a>’ block and make sure to include that in the imports at the top. </p>



<p>Now that we have our data stored and ready to be analyzed, we can go ahead and plot the data.</p>



<h2 class="wp-block-heading">Plotting The Data</h2>



<p>I am going to show some simple plots you can make with <a href="https://blog.finxter.com/how-to-change-the-figure-size-for-a-seaborn-plot/" target="_blank" rel="noreferrer noopener">Seaborn</a>, an excellent tool to make nice-looking graphs and plots.  The documentation is <a href="https://seaborn.pydata.org/" target="_blank" rel="noreferrer noopener">here</a> yet, there are several good articles and videos on <a href="https://blog.finxter.com/" target="_blank" rel="noreferrer noopener">finxter.com</a> if you want to see some more advanced implementations, like <a href="https://blog.finxter.com/heatmaps-with-seaborn/" target="_blank" rel="noreferrer noopener">this article making heatmaps of COVID data</a>. </p>



<p>First, we need to put the data into a <a href="https://blog.finxter.com/pandas-quickstart/" target="_blank" rel="noreferrer noopener">pandas</a> DataFrame, turn the dates in the month column from strings back into <code>datetime</code> objects so that the months can be properly ordered in time, and then sort the data by both month and news source (although sorting by news source is not entirely necessary).  I use ‘<code>inplace=True</code>’ so that the DataFrame remains properly sorted throughout the entire kernel.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># set the dataframe, convert the date column from a string, and then sort so the data is plotted correctly
df = pd.read_csv('combined.csv')
df['Month'] = pd.to_datetime(df['Month']).dt.strftime("%Y-%m")
df.sort_values(by=['Month', 'News Source'], inplace=True)
</pre>



<p>Now we can <a href="https://blog.finxter.com/matplotlib-full-guide/" target="_blank" rel="noreferrer noopener" title="Matplotlib — A Simple Guide with Videos">plot </a>our data.</p>



<p>Since the reason we plot graphs is to answer certain questions that we have about some data, let’s ask a few questions ourselves and see what the results give us.&nbsp; First: are ABC, CNN, and Fox News in general favorably inclined, neutral, or maybe negatively inclined towards the President?&nbsp; Have they been consistent in their reporting this past year?&nbsp; If not, did something happen that might have led to opinion changing in either direction?</p>



<p>Let’s plot a simple <a href="https://blog.finxter.com/matplotlib-line-plot/" target="_blank" rel="noreferrer noopener" title="Matplotlib Line Plot – A Helpful Illustrated Guide">line graph</a> over time of the average polarity per month for ABC, CNN, and Fox News.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># line chart of the average polarity per month for each source
# sns.set(rc={'figure.figsize':(15,10)})
sns.lineplot(x = 'Month', y = 'Polarity', hue='News Source', ci=None, data = df)
</pre>



<div class="wp-block-image"><figure class="aligncenter size-full"><img fetchpriority="high" decoding="async" width="751" height="479" src="https://blog.finxter.com/wp-content/uploads/2021/09/image-25.png" alt="" class="wp-image-35057" srcset="https://blog.finxter.com/wp-content/uploads/2021/09/image-25.png 751w, https://blog.finxter.com/wp-content/uploads/2021/09/image-25-300x191.png 300w" sizes="(max-width: 751px) 100vw, 751px" /></figure></div>



<p>We can also use <a href="https://blog.finxter.com/display-modify-and-save-images-with-matplotlib/" target="_blank" rel="noreferrer noopener" title="How to Display, Modify and Save Images in Matplotlib">bar graphs</a> if we want to visualize the data differently.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># bar chart of the average polarity per month for each source
sns.barplot(y = 'Polarity', x = 'Month', hue='News Source', ci=None, data = df)
</pre>



<div class="wp-block-image"><figure class="aligncenter size-full"><img decoding="async" width="729" height="445" src="https://blog.finxter.com/wp-content/uploads/2021/09/image-26.png" alt="" class="wp-image-35058" srcset="https://blog.finxter.com/wp-content/uploads/2021/09/image-26.png 729w, https://blog.finxter.com/wp-content/uploads/2021/09/image-26-300x183.png 300w" sizes="(max-width: 729px) 100vw, 729px" /></figure></div>



<p>By setting a hue, we allow the news sources to be grouped out and analyzed separately.  We set ‘<code>ci=None</code>’ so that the <a href="https://blog.finxter.com/how-to-plot-the-confidence-interval-in-python/" target="_blank" rel="noreferrer noopener" title="How to Plot the Confidence Interval in Python?">confidence interval </a>is not shown, otherwise the graphs would look messy.</p>



<p>The polarity is a study of how positively or negatively inclined a text is.  With a range from -1 (extremely negative) to 1 (extremely positive), the polarity can potentially tell us whether or not the text is favorably inclined towards its selected topic.  Having studied polarity data to analyze the positivity or negativity of the content, while the range for our data does not seem to be very broad given that the polarity can fall between -1 and 1, most articles generally fall between -0.2 and 0.3, even news outlets with a stronger political bent have their articles generally fall within this range as well.  There is a good article <a href="https://planspace.org/20150607-textblob_sentiment/" target="_blank" rel="noreferrer noopener">here</a> if you are interested to learn more about how <code>TextBlob</code> produces its sentiment scores.</p>



<p>With only these graphs, our questions are mostly answered.&nbsp; If you are an American, you would expect Fox News to have a less favorable opinion of a Democrat President and you would expect the opposite for CNN.&nbsp; ABC, in general, has managed to stay somewhat in the middle.&nbsp;</p>



<p>From September to November of last year the United States had their elections, so it would be natural for CNN, and even ABC, to throw more of their weight behind a candidate they would much rather have than ex-President Trump.&nbsp; On the other hand, in August of this year, the USA had its disastrous troop pullout from Afghanistan which many Americans saw as an embarrassment to the country.&nbsp; This is certainly reflected in the low polarity score for the month from Fox News.&nbsp; Even the other news outlets did not seem to like what happened.</p>



<p>If you are curious to analyze the distribution of polarity values for each news outlet, we can make a quick histogram for August.  We can isolate all the data from August using ‘<code>get_group()</code>’ after grouping our entire <code>DataFrame</code> by month, then we can make our plot with ‘<code>sns.histplot</code>’, setting <code>x</code> to ‘<code>polarity</code>’, the hue to ‘<code>News Source</code>’ so that a separate plot appears for each outlet, and the <em>kde</em> (kernel density estimate) to ‘<code>True</code>’ to smooth the distributions and produce drawn lines for us.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">aug = df.groupby(['Month']).get_group('2021-08')
# months.head()
sns.histplot(data=aug, hue='News Source', x='Polarity', kde=True)
</pre>



<p>Here is our data:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="738" height="483" src="https://blog.finxter.com/wp-content/uploads/2021/09/image-27.png" alt="" class="wp-image-35063" srcset="https://blog.finxter.com/wp-content/uploads/2021/09/image-27.png 738w, https://blog.finxter.com/wp-content/uploads/2021/09/image-27-300x196.png 300w" sizes="auto, (max-width: 738px) 100vw, 738px" /></figure></div>



<p>Since we selected a fairly balanced sampling of news sources, we can also make an interesting conclusion that the first year of Biden’s presidency was not particularly successful, given that there is a basic downward polarity trend among all our sources.</p>



<p>On the other hand, the subjectivity does not give away too much other than that maybe the charged atmosphere of the elections calmed down the reporting a little bit.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># line chart of the average subjectivity per month for each source
sns.lineplot(x = 'Month', y = 'Subjectivity', hue='News Source', ci=None, data = df)
</pre>



<p>The usual range of subjectivity scores of news articles hovers between .2 and .6 usually, so there is nothing here out of the ordinary.  Although you often see much higher scores from more politically extreme news sites.</p>



<p>Let’s now ask one more question before I end the article.  ABC tends to have a reputation of being a very balanced news source, although leaning just a little to the left politically.  In what was a very contentious political climate in the USA the past year, did the integrity of their reporting on Joe Biden hold up to their perceived reputation?</p>



<p><a href="https://blog.finxter.com/matplotlib-boxplot/" target="_blank" rel="noreferrer noopener" title="Matplotlib Boxplot – A Helpful Illustrated Guide">Box plots</a> might be our best choice here because the line plots we used before could not neatly show the distribution of article scores, we only saw what was the average.  All we need to do is group the DataFrame by the outlet and then use <code>get_group()</code> to isolate the data from ABC.  To make our chart look more colorful we can add a color palette, in this case, I use ‘<code>mako</code>.&#8217;</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">abc = df.groupby(['News Source']).get_group('abcnews.go.com')
sns.boxplot(x = 'Month', y = 'Polarity', data = abc, palette='mako')
sns.boxplot(x = 'Month', y = 'Subjectivity', data = abc, palette='mako')
</pre>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="742" height="456" src="https://blog.finxter.com/wp-content/uploads/2021/09/image-28.png" alt="" class="wp-image-35065" srcset="https://blog.finxter.com/wp-content/uploads/2021/09/image-28.png 742w, https://blog.finxter.com/wp-content/uploads/2021/09/image-28-300x184.png 300w" sizes="auto, (max-width: 742px) 100vw, 742px" /></figure></div>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="721" height="413" src="https://blog.finxter.com/wp-content/uploads/2021/09/image-29.png" alt="" class="wp-image-35066" srcset="https://blog.finxter.com/wp-content/uploads/2021/09/image-29.png 721w, https://blog.finxter.com/wp-content/uploads/2021/09/image-29-300x172.png 300w" sizes="auto, (max-width: 721px) 100vw, 721px" /></figure></div>



<p>It seems as if we can say the data confirms the opinion.  Even the events in August did not have too much of an effect on the reporting of Joe Biden.  If we wish, we can compare the data to Fox News on a single chart.  We can concatenate together two individual DataFrames from each news outlet and chart the data.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># compare ABC and Fox polarity data side-by-side
fox = df.groupby(['News Source']).get_group('foxnews.com')
abc = df.groupby(['News Source']).get_group('abcnews.go.com')
a_f = pd.concat([abc, fox])
sns.boxplot(x = 'Month', y = 'Polarity', hue='News Source', data = a_f)
</pre>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="738" height="503" src="https://blog.finxter.com/wp-content/uploads/2021/09/image-30.png" alt="" class="wp-image-35067" srcset="https://blog.finxter.com/wp-content/uploads/2021/09/image-30.png 738w, https://blog.finxter.com/wp-content/uploads/2021/09/image-30-300x204.png 300w" sizes="auto, (max-width: 738px) 100vw, 738px" /></figure></div>



<p>Since the Fox News data seems to be more varied we can certainly say that compared to Fox News ABC is more balanced, at least on its reporting about the current President.</p>



<p>Given that arguably the 3 most popular news outlets in the USA are increasingly negative on the topic of Joe Biden, we may be able to conclude that the President may need to do something to improve his popularity nationwide.&nbsp; However, a more in-depth analysis is required.</p>



<p>This concludes our series on news article scraping and analysis with the help of <a href="https://blog.finxter.com/how-to-generate-a-word-cloud-with-newspaper3k-and-python/" target="_blank" rel="noreferrer noopener">Newspaper3k</a>, a tool that allows you to scrape massive amounts of news article data with only a couple of lines of code. </p>



<p>I have also included more graphs and code in my video above or on my <a href="https://github.com/finxter/Articles" target="_blank" rel="noreferrer noopener" title="https://github.com/finxter/Articles">Github.</a></p>
<p>The post <a href="https://blog.finxter.com/analyzing-news-articles-with-newspaper3k-textblob-and-seaborn/">Analyzing News Articles with Newspaper3k, TextBlob, and Seaborn</a> appeared first on <a href="https://blog.finxter.com">Be on the Right Side of Change</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Newspaper3k &#8211; How to Generate a Word Cloud in Python</title>
		<link>https://blog.finxter.com/how-to-generate-a-word-cloud-with-newspaper3k-and-python/</link>
		
		<dc:creator><![CDATA[Craig Helstowski]]></dc:creator>
		<pubDate>Sat, 28 Aug 2021 10:14:29 +0000</pubDate>
				<category><![CDATA[Newspaper3k]]></category>
		<category><![CDATA[Web Scraping]]></category>
		<guid isPermaLink="false">https://blog.finxter.com/?p=34485</guid>

					<description><![CDATA[<p>To carry on from our introduction to Newspaper3k, we can now take our basic knowledge and realize the possibilities of what we can do with this library. Here I’m going to demonstrate for you a project which takes articles from a set of different news agencies, picks out the most used words from them, and ... <a title="Newspaper3k &#8211; How to Generate a Word Cloud in Python" class="read-more" href="https://blog.finxter.com/how-to-generate-a-word-cloud-with-newspaper3k-and-python/" aria-label="Read more about Newspaper3k &#8211; How to Generate a Word Cloud in Python">Read more</a></p>
<p>The post <a href="https://blog.finxter.com/how-to-generate-a-word-cloud-with-newspaper3k-and-python/">Newspaper3k &#8211; How to Generate a Word Cloud in Python</a> appeared first on <a href="https://blog.finxter.com">Be on the Right Side of Change</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-4-3 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="Newspaper3k – How to Generate a Word Cloud in Python" width="937" height="527" src="https://www.youtube.com/embed/aGgnM-Eu3Wg?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<p>To carry on from our introduction to <a href="https://blog.finxter.com/newspaper3k-a-python-library-for-fast-web-scraping/" target="_blank" rel="noreferrer noopener" title="Newspaper3k – A Python Library For Fast Web Scraping">Newspaper3k</a>, we can now take our basic knowledge and realize the possibilities of what we can do with this library.</p>



<p>Here I’m going to demonstrate for you a project which takes articles from a set of different news agencies, picks out the most used words from them, and shows a word cloud of the results with the help of <a href="https://blog.finxter.com/6-best-python-nlp-libraries/" target="_blank" rel="noreferrer noopener" title="6 Best Python NLP Libraries">NLP </a>and <a href="https://blog.finxter.com/matplotlib-full-guide/" target="_blank" rel="noreferrer noopener" title="Matplotlib — A Simple Guide with Videos">Matplotlib</a>.</p>



<p>You can check out the full code on <a href="https://github.com/finxter/Articles" title="https://github.com/finxter/Articles" target="_blank" rel="noreferrer noopener">GitHub here</a>. </p>



<p>Let’s get started.</p>



<h2 class="wp-block-heading">Introduction</h2>



<p>In this article, we are going to scrape a series of articles from several different news sources and once we have extracted the keywords from each of the articles we can create a word cloud that displays the most important topics of the day from the keywords obtained from each article using <a href="https://newspaper.readthedocs.io/en/latest/" target="_blank" rel="noreferrer noopener" title="https://newspaper.readthedocs.io/en/latest/">Newspaper3k</a>.</p>



<p><a href="https://en.wikipedia.org/wiki/Tag_cloud" target="_blank" rel="noreferrer noopener" title="https://en.wikipedia.org/wiki/Tag_cloud"><strong>Word clouds</strong> </a>may not be the most penetrating way to analyze text data but, can be a very engaging and simple means for analyzing text data and discovering words or common word patterns that frequently appear. For example, if you are able to get text of speeches or writings of a public figure, you can easily visualize the most important topics that are covered with a word cloud.&nbsp; To take it further, companies could combine this with sentiment analysis to find out which of their products are written about the most and how positively or negatively viewed they are.&nbsp;</p>



<p>For example, here is a word cloud from <em>‘Laudato Si’</em>,&nbsp; a Vatican encyclical put out 6 years ago.&nbsp; The document is about 250 pages, however we can very quickly get the gist of what the encyclical is about by looking at the 100 most-used words in the paper:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="530" height="271" src="https://blog.finxter.com/wp-content/uploads/2021/08/image-34.png" alt="" class="wp-image-34487" srcset="https://blog.finxter.com/wp-content/uploads/2021/08/image-34.png 530w, https://blog.finxter.com/wp-content/uploads/2021/08/image-34-300x153.png 300w" sizes="auto, (max-width: 530px) 100vw, 530px" /></figure></div>



<p>Depending on the text we are analyzing, we can maybe even determine the basic theme or arguments of the paper just from looking at a word cloud.&nbsp; As we can see from the word cloud of this paper, we can guess that the encyclical concerns matters of the planet and humanity, that there is some sort of problem and something must be done to help the planet, maybe for the good of ‘us’ or humanity, maybe for God as well.&nbsp;As we see, creating a word cloud with the help of Newspaper3k and data analysis can give us a lot of information about a text in a single picture.</p>



<p>Now that we see the possibilities here, let’s begin to make our own word clouds.</p>



<h2 class="wp-block-heading">Scrape a Set of Articles From Different News Sources</h2>



<p>Given all of the news recently about the American troop withdrawal from Afghanistan, we will focus on news about the United States for this project.&nbsp; We will collect the RSS feeds from the following news sources: ABC News, NBC News, CBS News, RT News, The Guardian, and the New York Times.&nbsp; The link to the feeds will be in the code so you do not have to search for them.</p>



<p>As mentioned in <a href="https://blog.finxter.com/newspaper3k-a-python-library-for-fast-web-scraping/" target="_blank" rel="noreferrer noopener">our previous article</a>, RSS feeds allow us to quickly and with great ease scrape article links, especially for today’s news.&nbsp; If this is your first introduction to web scraping or Newspaper3k, I encourage you to read it so you understand how RSS feeds work, how to <a href="https://blog.finxter.com/python-freelancing-fiverr-gig-webscraping/" target="_blank" rel="noreferrer noopener" title="https://blog.finxter.com/python-freelancing-fiverr-gig-webscraping/">scrape </a>them, and the python libraries you may need to download before you begin.&nbsp;The <a href="https://blog.finxter.com/newspaper3k-a-python-library-for-fast-web-scraping/" target="_blank" rel="noreferrer noopener" title="https://blog.finxter.com/newspaper3k-a-python-library-for-fast-web-scraping/">video</a> also shows you how to setup a <a href="https://blog.finxter.com/python-virtual-environments-conda/" target="_blank" rel="noreferrer noopener" title="Python Virtual Environments with Conda — Why the Buzz?">virtual environment</a> to run the program from the folder from which will run your code.</p>



<p>Let’s begin.</p>



<p>First we will <a href="https://blog.finxter.com/how-to-import-libraries-in-pythons-exec-function/" target="_blank" rel="noreferrer noopener" title="How to Import Libraries in Python’s exec() Function?">import </a>some necessary libraries and collect all of our feeds and put them into a <a href="https://blog.finxter.com/python-lists/" target="_blank" rel="noreferrer noopener" title="The Ultimate Guide to Python Lists">list</a>:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import requests
from bs4 import BeautifulSoup
from newspaper import Article
import csv

feeds = [
         'https://www.nbcnews.com/rss', 
         'https://www.theguardian.com/us/rss', 
         'https://www.rt.com/rss/usa/', 
         'https://abcnews.go.com/abcnews/usheadlines', 
         'https://www.cbsnews.com/latest/rss/us', 
         'https://rss.nytimes.com/services/xml/rss/nyt/HomePage.xml'
]
</pre>



<p>Now let’s scrape for the articles.&nbsp;Luckily for us, all of the RSS feeds here can be scraped exactly the same.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">articles = []

for feed in feeds:
    response = requests.get(feed)
    webpage = response.content
    soup = BeautifulSoup(webpage, features='xml')

    # every article link will be found in an item tag
    items = soup.find_all('item')

    # extract the link
    for item in items:
        link = item.find('link').text
        articles.append(link)
</pre>



<p>In an RSS feed, every article link will be included in its own separate <code>&lt;item&gt;</code> tag.&nbsp; We can simply just look for every instance of the <code>&lt;item&gt;</code> tag and collect the link in the <code>&lt;link&gt;</code> tag inside.</p>



<p>Now that we have our list of articles, it’s time to scrape each article using the Newspaper3k library.&nbsp; Then we will store the data in a <a href="https://blog.finxter.com/how-to-read-a-csv-file-into-a-python-list/" target="_blank" rel="noreferrer noopener" title="How to Read a CSV File Into a Python List?">CSV </a>file.&nbsp; For this article, we will save the URL, the article keywords, and the text (in case we would like to do further analysis of the text).&nbsp;</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Data = []

for url in articles:
    info = Article(url)
    info.download()
    info.parse()
    info.nlp()

    keywords = info.keywords
    text = info.text

    # save the URL, the keywords, and the text
    save = [url, keywords, text]
    data.append(save)  


with open('MyCSV.csv', 'w') as csv_file:
    # set the column labels for the CSV file
    label = ['URL', 'Keywords', 'Text']

    # write the data into the CSV file
    writer = csv.writer(csv_file)
    writer.writerow(label)
    writer.writerows(data)
    csv_file.close()
</pre>



<h2 class="wp-block-heading">Display a Word Cloud From the Data</h2>



<p>Now that we have all of our data stored, we can now let the fun begin and create our word clouds.</p>



<p>Before we develop our big word cloud from all of the articles, I will show you how to quickly create a word cloud from just one article.</p>



<p>First, if you do not have Jupyter notebooks on your computer, the following commands will install it:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">conda install -c conda-forge notebook</pre>



<p>or</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">pip install notebook</pre>



<p>Then the following command will open up Jupyter notebooks:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">jupyter notebook</pre>



<p>Jupyter will then open up in your browser and you can begin work.</p>



<h3 class="wp-block-heading">Creating Simple Word Clouds</h3>



<p>Let’s first install again the necessary libraries.&nbsp; We will need <a href="https://blog.finxter.com/pandas-quickstart/" target="_blank" rel="noreferrer noopener" title="10 Minutes to Pandas (in 5 Minutes)">pandas </a>to read the CSV data, we are going to import the <code>wordcloud</code> library to create our word cloud image, and we will need <a href="https://blog.finxter.com/best-matplotlib-cheat-sheet/" target="_blank" rel="noreferrer noopener" title="Best Matplotlib Cheat Sheet">Matplotlib </a>to display the word cloud.&nbsp; If you need to install the three libraries this will suffice:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">pip install pandas
pip install matplotlib
pip install wordcloud</pre>



<p>Now the code:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import pandas as pd
from wordcloud import WordCloud, STOPWORDS

import matplotlib.pyplot as plt
</pre>



<p>Now what we need to do is load the data from the CSV file we just saved and create a data frame.&nbsp; Make sure to not load the first row as that just has the titles for each column.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># Load in the dataframe
# converters={'Keywords': eval} → to convert each row of keywords back into a list
df = pd.read_csv('MyCSV2.csv', converters={'Keywords': eval})

#if you want to see how many rows of data you have
print(df.shape[0])

# if you wish to display the data
df.head</pre>



<p>Here is how the first couple of rows of my data look like:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="664" height="137" src="https://blog.finxter.com/wp-content/uploads/2021/08/image-35.png" alt="" class="wp-image-34489" srcset="https://blog.finxter.com/wp-content/uploads/2021/08/image-35.png 664w, https://blog.finxter.com/wp-content/uploads/2021/08/image-35-300x62.png 300w" sizes="auto, (max-width: 664px) 100vw, 664px" /></figure></div>



<p>Setting the converters as we did for the ‘Keywords’ column is necessary to convert each row of keywords back into a list that we originally saved into the CSV file.&nbsp; Without this, each row of keywords will simply be one big string that will be a pain to deal with.</p>



<p>Just so you know how to create a word cloud from a single article we will make one first from a single article.&nbsp; Since it is not necessary to print a word cloud from the keywords of a single article, we will just develop the word cloud from the text of the article.</p>



<p>We include a set of ‘stopwords’ already included in the Wordcloud library that remove useless words like ‘the’, ‘we’, etc. that would add clutter to the wordcloud.&nbsp; If you wish to add more stopwords you can type stopwords.add(“<em>your word</em>”).</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># Start with one review:
text = df.Text[177]
# text = " ".join(i for i in keywords)
print(df.URL[177])
https://www.rt.com/usa/532248-lake-mead-water-shortage/?utm_source=rss&utm_medium=rss&utm_campaign=RSS

# stopwords is simply a set of words to be eliminated
# if STOPWORDS not manually set, then this default list will be used
stopwords = set(STOPWORDS)

#if you want to add to the stopwords list, here I add some news sources
stopwords.update(['s','t','rt','co','abc','nbc','cbs','nytimes'])

# Create and generate a basic word cloud image:
wordcloud = WordCloud(stopwords=stopwords,max_words=50,background_color="white").generate(text)

# Display the generated image:
plt.figure(figsize=[10,10])
plt.imshow(wordcloud)
plt.axis("off")
plt.show()
</pre>



<p>Here is what my word cloud looks like from this article:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="554" height="283" src="https://blog.finxter.com/wp-content/uploads/2021/08/image-36.png" alt="" class="wp-image-34490" srcset="https://blog.finxter.com/wp-content/uploads/2021/08/image-36.png 554w, https://blog.finxter.com/wp-content/uploads/2021/08/image-36-300x153.png 300w" sizes="auto, (max-width: 554px) 100vw, 554px" /></figure></div>



<p>As we can see, this article is about some water shortage in either Nevada or Arizona.</p>



<p>Now that we know how to create a basic word cloud from a single article, let’s now expand that to find the most important key topics of the day from a large set of articles.</p>



<p>It will not be necessary to run our analysis from the text of each article (although you can if you wish), so we will just create a word cloud from all of the keywords extracted.</p>



<p>First we need to gather all of the keywords, put them into a single list, and then get them all out of the list and formatted as a big text.&nbsp; With a little ‘python-fu’ it can easily be done:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">#for row(i) in df.Keywords
#    for keyword(j) in i
#        append j
keywords = [j for i in df.Keywords for j in I]

# join all of the keywords into a single string text
text = " ".join(i for i in keywords)

#print(text)
</pre>



<p>Now we have a full text of all of our keywords ready to be made into a word cloud.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># collocation=False so that duplicate words do not appear as part of a larger phrase (like 'president Biden')
wordcloud = WordCloud(stopwords=stopwords,max_words=100,background_color="white",collocations=False).generate(text)

# Display the generated image:
plt.figure(figsize=[10,10])
plt.imshow(wordcloud)
plt.axis("off")
plt.show()
</pre>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="606" height="310" src="https://blog.finxter.com/wp-content/uploads/2021/08/image-37.png" alt="" class="wp-image-34491" srcset="https://blog.finxter.com/wp-content/uploads/2021/08/image-37.png 606w, https://blog.finxter.com/wp-content/uploads/2021/08/image-37-300x153.png 300w" sizes="auto, (max-width: 606px) 100vw, 606px" /></figure></div>



<p>As we can see, the most used keywords just happen to be involved in the most important topics in the United States today: Afghanistan and COVID-19.&nbsp; Especially events in Afghanistan are dominating the headlines.</p>



<h3 class="wp-block-heading">Getting a Little Creative With Our Word Cloud</h3>



<p>For kicks, I will show you a how you can have a little fun creating your word cloud.&nbsp; It does not just simply have to look like the one above.&nbsp;</p>



<p>Since we are dealing with news from the United States, why don’t we create a word cloud in the shape and color of the American flag?</p>



<p>First, find a picture of the flag and then save it as a PNG file.&nbsp; Here is the link to the image I used:</p>



<ul class="wp-block-list"><li><a href="https://cdn.britannica.com/33/4833-004-828A9A84/Flag-United-States-of-America.jpg" target="_blank" rel="noreferrer noopener">https://cdn.britannica.com/33/4833-004-828A9A84/Flag-United-States-of-America.jpg</a></li></ul>



<p>Now we will load it into our program and create a word cloud that looks like the American flag.</p>



<p>You will need to <code>pip install numpy</code> and <a href="https://blog.finxter.com/python-install-pil/" target="_blank" rel="noreferrer noopener" title="How to Install PIL/Pillow in Python? A Helpful Illustrated Guide">Pillow</a> if you do not have it.&nbsp;</p>



<p>Now our code:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import numpy as np
from PIL import Image
from wordcloud import ImageColorGenerator

# Generate a word cloud image
frame = np.array(Image.open("usa.png"))

wordcloud = WordCloud(stopwords=stopwords, background_color="white", max_words=500, collocations=False, mask=frame).generate(text)

# create coloring from image
image_colors = ImageColorGenerator(frame)

plt.figure(figsize=[15,15])
#add the color scheme to the word cloud
plt.imshow(wordcloud.recolor(color_func=image_colors))
plt.axis("off")
plt.show()
</pre>



<p>We take the image and create a mask, or a frame, which directs where the words can go and what colors they will be based on an array of numerical values that maps to the image we put in.&nbsp; That mask is then included into the Wordcloud object.&nbsp; Finally, we then get the colors necessary which will then go into our new word cloud from <code>ImageColorGenerator</code>.</p>



<p>In this case I added a couple extra hundred words to fill in the flag a little more so you can see how the program fits the words to the shape and contours of the flag.</p>



<p>Here is our new ‘American’ word cloud now:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="664" height="353" src="https://blog.finxter.com/wp-content/uploads/2021/08/image-38.png" alt="" class="wp-image-34492" srcset="https://blog.finxter.com/wp-content/uploads/2021/08/image-38.png 664w, https://blog.finxter.com/wp-content/uploads/2021/08/image-38-300x159.png 300w" sizes="auto, (max-width: 664px) 100vw, 664px" /></figure></div>



<p>Enjoy!</p>



<p>If you want a link to the code and the CSV I used, I have included it on <a href="https://github.com/Boniface8/Articles/blob/main/WordCloud.ipynb" target="_blank" rel="noreferrer noopener">my GitHub</a>.</p>
<p>The post <a href="https://blog.finxter.com/how-to-generate-a-word-cloud-with-newspaper3k-and-python/">Newspaper3k &#8211; How to Generate a Word Cloud in Python</a> appeared first on <a href="https://blog.finxter.com">Be on the Right Side of Change</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Newspaper3k – A Python Library For Fast Web Scraping</title>
		<link>https://blog.finxter.com/newspaper3k-a-python-library-for-fast-web-scraping/</link>
		
		<dc:creator><![CDATA[Craig Helstowski]]></dc:creator>
		<pubDate>Wed, 18 Aug 2021 14:06:55 +0000</pubDate>
				<category><![CDATA[Machine Learning]]></category>
		<category><![CDATA[Newspaper3k]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Web Scraping]]></category>
		<guid isPermaLink="false">https://blog.finxter.com/?p=34047</guid>

					<description><![CDATA[<p>Would you like to be able to scrape information from any article without having to write a completely different set of code every time? In this post, I will show you a Python library which allows you to scrape any article using only a few lines of code.&#160; It’s called Newspaper3k. ? Video:&#160;As you go ... <a title="Newspaper3k – A Python Library For Fast Web Scraping" class="read-more" href="https://blog.finxter.com/newspaper3k-a-python-library-for-fast-web-scraping/" aria-label="Read more about Newspaper3k – A Python Library For Fast Web Scraping">Read more</a></p>
<p>The post <a href="https://blog.finxter.com/newspaper3k-a-python-library-for-fast-web-scraping/">Newspaper3k – A Python Library For Fast Web Scraping</a> appeared first on <a href="https://blog.finxter.com">Be on the Right Side of Change</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Would you like to be able to scrape information from any article without having to write a completely different set of code every time?</p>



<p>In this post, I will show you a Python library which allows you to scrape any article using only a few lines of code.&nbsp; It’s called <strong><em>Newspaper3k</em></strong>.</p>



<p class="has-black-color has-cyan-bluish-gray-background-color has-text-color has-background">? <strong>Video</strong>:&nbsp;As you go through the article, you can also watch my explainer video presenting the code snippet introduced here&#8212;in an easy-to-follow, step-by-step manner:</p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="Newspaper3k – A Python Library For Fast Web Scraping" width="937" height="527" src="https://www.youtube.com/embed/g4XyKd3VgoA?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<h2 class="wp-block-heading">Why?</h2>



<p>Let’s start by asking why <a href="https://blog.finxter.com/web-scraping-with-beautifulsoup-in-python/" target="_blank" rel="noreferrer noopener" title="Web Scraping With BeautifulSoup In Python">scraping </a>news or blog articles ‘en masse’ is so useful.&nbsp; Some of the reasons include the following:</p>



<ul class="wp-block-list"><li>A business wants to discover <strong><em>trends </em></strong>or to search what people are saying about their company in order to make more informed decisions.</li><li>Some individual or service wants to collect and <strong><em>aggregate news</em></strong>.</li><li>For a <strong><em>research project</em></strong>, such as discovering what news is real and what news is fake for example, researchers may need a large set of articles to collect.</li><li>A journalist could look to gather articles that back his <strong><em>claims </em></strong>or arguments made in articles he wrote.</li></ul>



<p>In today’s world, there is an overwhelming amount of news available on the internet. Therefore, if you have to scrape articles it is important to know what information to look for, where to find it, and extract the information you need without wasting time. You do not need to be a professional to understand this. We all deal with content from various sources in our daily lives and we can intuit very well what we need, what we don’t need, and what attracts our curiosity enough that we may want to explore further. How much time we would waste if we did not know how to sift through all of this information!</p>



<p>However, if you must program a web scraper it can be a drag to have to search the HTML or CSS every time and write a new set of code for every site you need to scrape. The task is made even more difficult if the content is dynamically loaded. Wouldn’t it be much easier if you can scrape all the information you need from any article using the same couple of lines of code?</p>



<p>It is here where the power of Python shines again. With the Newspaper3k library, you can <strong><em>extract article data for almost any news service or blog with only the same few lines of code.</em></strong></p>



<h2 class="wp-block-heading">What is Newspaper3k?</h2>



<p>Newspaper3k is a Python library used for scraping web articles. It utilizes the requests library and has <a href="https://academy.finxter.com/university/web-scraping-with-beautifulsoup/" target="_blank" rel="noreferrer noopener" title="https://academy.finxter.com/university/web-scraping-with-beautifulsoup/">BeautifulSoup </a>as a dependency while it parses for <code>lxml</code>. Newspaper3k is not only able to scrape the entire article text for you, but can also scrape for other kinds of data such as the publish date, author(s), URL, images, and video to name a few. If you wish to simply know what the article is about without having to read the whole article, Newspaper3k can also produce a summary of the article.</p>



<p>After you extract the data it can then be integrated and saved into different formats such as <a href="https://blog.finxter.com/how-to-read-a-csv-file-into-a-python-list/" target="_blank" rel="noreferrer noopener" title="How to Read a CSV File Into a Python List?">CSV</a>, <a href="https://blog.finxter.com/how-to-get-json-from-url-in-python/" target="_blank" rel="noreferrer noopener" title="How to Get JSON from URL in Python?">JSON</a>, and even <a href="https://blog.finxter.com/pandas-quickstart/" target="_blank" rel="noreferrer noopener" title="10 Minutes to Pandas (in 5 Minutes)">pandas</a>.&nbsp; Newspaper3k also works in over 30 languages.</p>



<p>The Newspaper3k Python library can also do more advanced functions such as discovering RSS feeds, scraping for article URLs from a main news source, and even multi-thread extraction if you have to scrape for more than one article but cannot afford to bombard a website with so many requests.</p>



<p>I will now show you 2 sample demonstrations using Newspaper3k.&nbsp; The first is a very simple article scraper.&nbsp; In the second demonstration, I will show you how Newspaper3k allows you to do speedy sentiment analysis on news articles.</p>



<h2 class="wp-block-heading">A Simple Article Scraper Using Newspaper3k</h2>



<p>Here I will show you how you can scrape a single article in only a couple lines of code.</p>



<p>To first use Newspaper3k, we must install the package first:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">pip3 install Newspaper3k</pre>



<p>Now let’s write the code.&nbsp; We will choose this article as our example to scrape:</p>



<p><a href="https://www.cnbc.com/2021/02/02/5-freelance-jobs-where-you-can-earn-100000-or-more-during-pandemic.html" target="_blank" rel="noreferrer noopener">5 freelance jobs where you can earn $100,000 or more during the pandemic</a></p>



<p>Let’s first extract the information and then store the data from the parsed article object into their appropriate variables:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">from newspaper import Article

# create an article object
article = Article('https://www.cnbc.com/2021/02/02/5-freelance-jobs-where-you-can-earn-100000-or-more-during-pandemic.html')
article.download()
article.parse()
article.nlp()

title = article.title
link = article.url
authors = article.authors
date = article.publish_date
image = article.top_image
summary = article.summary
text = article.text
</pre>



<p>We first need to import the Article object from the Newspaper3k library and then we can extract the information.&nbsp; Following the order shown is necessary.&nbsp; We must also include the <code>nlp()</code> function in order for us to process the keywords from the article using <em>Natural Language Processing</em> (NLP) and to also summarize the article.</p>



<p>Now that we have the information stored, we can <a href="https://blog.finxter.com/python-print/" target="_blank" rel="noreferrer noopener" title="Python print()">print </a>out our data:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">print('**********************************')
print(f'Title: {title}')
print(f'Link: {link}')
print(f'Author: {authors[0]}')
print(f'Publish Date: {date}')
print(f'Top Image: {image}')
print(f'Summary: ')
print(summary)
print('**********************************')
</pre>



<p>And the output:</p>



<div class="wp-block-image"><figure class="aligncenter size-full is-resized"><img loading="lazy" decoding="async" src="https://blog.finxter.com/wp-content/uploads/2021/08/image-25.png" alt="" class="wp-image-34049" width="664" height="112" srcset="https://blog.finxter.com/wp-content/uploads/2021/08/image-25.png 664w, https://blog.finxter.com/wp-content/uploads/2021/08/image-25-300x51.png 300w" sizes="auto, (max-width: 664px) 100vw, 664px" /></figure></div>



<p>Not too bad for only a couple of lines, don’t you think?</p>



<h2 class="wp-block-heading">An Article Sentiment Analysis Program With Newspaper3k</h2>



<p>Now I will show you a more expanded demonstration in which we will collect articles from a news source and then print out a summary of each article with its corresponding link and sentiment scores.&nbsp; The sentiment scores will display the polarity and subjectivity scores for each article.</p>



<p>Let’s say we are doing a sentiment analysis of articles from a particular website.&nbsp; In this case, we will select <a href="https://abcnews.go.com/Technology/" target="_blank" rel="noreferrer noopener">ABC Technology News</a>.&nbsp; We first need to find a way to gather a collection of articles from the news site for us to scrape.</p>



<p>A very easy way to collect article links from a news source is to get its RSS feed if it is available.&nbsp;</p>



<h3 class="wp-block-heading">What Is an RSS Feed and Why They Are Useful to Scrape</h3>



<p>RSS stands for ‘Really Simple Syndication.”&nbsp; These feeds allow the content from a website to be shared and distributed to other services much easier.&nbsp; Users can streamline content from any news source to their content aggregator service (such as Flipboard).&nbsp; On the other hand, news sources can use RSS to broaden the reach of their content delivery to potentially attract more readers.&nbsp; RSS feeds are often included in email content delivery services as well.</p>



<p>RSS feeds for web scraping are incredibly useful for two reasons.&nbsp; First, the article links are organized and formatted in such a way that they are very easy to find and extract in comparison to a regular website. The second reason is that almost all RSS feeds have the same standard format.&nbsp; Therefore the same code can often be used if you wish to extract article links from more than one RSS feed.&nbsp;</p>



<p>It must be said, scraping RSS feeds is no different than scraping regular websites.&nbsp; Make sure you are able to legally scrape the data from an RSS feed before going ahead and doing so.&nbsp; Some news sources have limitations on what you can do with RSS data.&nbsp; Therefore, before you decide to scrape a feed make sure to go to the news site and check to see if they have any RSS policies.&nbsp; Once you believe it is okay to scrape the RSS feed make sure to follow proper scraping practices such as not bombarding the site with too many requests and respecting the Terms and Conditions.&nbsp;</p>



<h3 class="wp-block-heading">Coding the Program</h3>



<p><strong><em>Step 1. Get the article links in the RSS feed.</em></strong></p>



<p>In this case ABC Technology does have an RSS feed, so we will use it.</p>



<p>To parse the links from the news source we must first look at the RSS feed and locate were each article link will be.&nbsp; As we see, each &lt;item&gt; tag has all of the details for each article in the feed.&nbsp; If we look under the &lt;item&gt; tag, we can see the article link under the &lt;link&gt; tag.&nbsp; This is where we will extract the links.</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="664" height="383" src="https://blog.finxter.com/wp-content/uploads/2021/08/image-26.png" alt="" class="wp-image-34050" srcset="https://blog.finxter.com/wp-content/uploads/2021/08/image-26.png 664w, https://blog.finxter.com/wp-content/uploads/2021/08/image-26-300x173.png 300w" sizes="auto, (max-width: 664px) 100vw, 664px" /></figure></div>



<p>We can now write a quick script using requests and <a href="https://blog.finxter.com/parsing-xml-using-beautifulsoup-in-python/" target="_blank" rel="noreferrer noopener" title="Parsing XML Using BeautifulSoup In Python">BeautifulSoup </a>to scrape for each of these links.&nbsp; If you have no experience using BeautifulSoup and requests, there are plenty of resources here on <a href="http://finxter.com/" target="_blank" rel="noreferrer noopener">finxter.com</a> to get you started, including many articles about <a href="https://blog.finxter.com/category/web-scraping/" target="_blank" rel="noreferrer noopener">web scraping</a>.</p>



<p>Here is how we will begin:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import requests
from bs4 import BeautifulSoup

feed = "https://abcnews.go.com/abcnews/technologyheadlines"

# first make a get request to the RSS feed
response = requests.get(feed)
# collect the contents of the request
webpage = response.content
# create a BeautifulSoup object that we can then parse to extract the links and title
soup = BeautifulSoup(webpage, features='xml')

# here we find every instance of an &lt;item> tag, collect everything inside each tag, and store them all in a list
items = soup.find_all('item')

# extract the article link within each &lt;item> tag and store in a separate list
articles = []
for item in items:
    link = item.find('link').text
    articles.append(link)
</pre>



<p>We first send a get request to the feed, and once inside, we take the content and store it in a BeautifulSoup object (here I use the ‘xml’ feature since the RSS feed is written in XML).&nbsp; Then we search for each <code>&lt;item&gt;</code> tag and store the data from each <code>&lt;item&gt;</code> instance into a <a href="https://blog.finxter.com/python-lists/" target="_blank" rel="noreferrer noopener" title="The Ultimate Guide to Python Lists">list </a>for us to further parse through.&nbsp; We will call this variable <em><code>items</code>.</em></p>



<p>We then loop through each element in<em> <code>items</code></em>, take the link out,and store each it in a new list which we will call <em>articles</em>.</p>



<p><strong><em>Step 2. </em>Now, let’s extract the data in each article.</strong></p>



<p>Now that we have all of the article links we can now collect the data we need from each article.&nbsp; We will extract the title, main keywords, summary, and text and store them each in its own separate variable:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">from newspaper import Article

# extract the data from each article, perform sentiment analysis, and then print
for url in articles:
    article = Article(url)
    article.download()
    article.parse()
    article.nlp()

    # store the necessary data in variables
    title = article.title
    summary = article.summary
    keywords = article.keywords
    text = article.text
</pre>



<p><strong><em>Step 3. It’s now time to do sentiment analysis.</em></strong></p>



<p>For this section, we are going to utilize the <a href="https://textblob.readthedocs.io/" target="_blank" rel="noreferrer noopener">Textblob</a> and <a href="https://www.nltk.org/" target="_blank" rel="noreferrer noopener">NLTK</a> libraries to process and analyze text.&nbsp; Therefore, before we begin we must <a href="https://blog.finxter.com/how-to-install-pip-on-windows/" target="_blank" rel="noreferrer noopener" title="How To Install pip On Windows?">install </a>both of the libraries.&nbsp; We can simply run <em><code><strong>pip install -U textblob</strong></code> </em>to install Textblob.&nbsp;</p>



<p>There is no need to enter a separate command to install NLTK as installing Textblob will also automatically install NLTK along with it.&nbsp; If you wish, however, you can install NLTK alone using <code><strong>pip install nltk</strong></code><em>.</em>&nbsp; &nbsp;&nbsp;</p>



<p>Textblob is a library that processes text and uses NLP to perform different kinds of analysis, such as sentiment analysis, classifying words into parts-of-speech, word translation, and more.&nbsp; It needs the <strong><em>Natural Language Toolkit</em></strong> (NLTK) library to run.&nbsp; It conducts sentiment analysis by averaging the scores for different word types in a text and then giving the text a polarity score and a subjectivity score.&nbsp; The polarity score is calculated from -1 to 1, -1 being extremely negative and 1 being extremely positive.&nbsp; The subjectivity score goes from 0 to 1, 0 being extremely subjective and 1 being extremely objective.</p>



<p>However, to conduct this analysis we need to tokenize the text in order for Textblob to actually read the text correctly.&nbsp; To tokenize simply means to break a text into smaller components such as words or sentences.&nbsp; The NLTK package will do this for us however, we need to download the ‘punkt’ package for us to do the tokenization:&nbsp;</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">from textblob import TextBlob
import nltk

nltk.download('punkt')
</pre>



<p>Now that I have explained a little what is going on behind the scenes, here is what the next section of code will look like (still in the ‘for’ <a href="https://blog.finxter.com/python-loops/" target="_blank" rel="noreferrer noopener" title="Python Loops">loop</a>):</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">for url in articles:
    ….
    # run sentiment analysis on the article text
    # create a Textblob object and then get the sentiment values and store them
    text_blob = TextBlob(text)
    polarity = text_blob.polarity
    subjectivity = text_blob.subjectivity
</pre>



<p><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <em>Step 4. Finally, we can now print out the data.</em></strong></p>



<p>Now that we have all of the data we need, we can now print the results:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">for url in articles:
    ….    
    # now we can print out the data
    print('**************************************')
    print(f'Title: {title}')
    print(f'URL: {url}')
    print(f'Keywords: {keywords}')
    print(f'Polarity: {polarity}')
    print(f'Subjectivity: {subjectivity}')
    print(f'Summary: ')
    print(summary)
    print('**************************************')
</pre>



<p>Here is what a sample of the output will look like:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="664" height="206" src="https://blog.finxter.com/wp-content/uploads/2021/08/image-27.png" alt="" class="wp-image-34051" srcset="https://blog.finxter.com/wp-content/uploads/2021/08/image-27.png 664w, https://blog.finxter.com/wp-content/uploads/2021/08/image-27-300x93.png 300w" sizes="auto, (max-width: 664px) 100vw, 664px" /></figure></div>



<p>If you want to take the code further and do more analysis, the possibilities are endless of what you can do.&nbsp; For example, you can write a quick script to select only articles above a certain subjectivity level, or you can make a comparison graph of polarity values from different sections in a news site.</p>



<p>For more information, I encourage you to check out the Newspaper3k <a href="https://newspaper.readthedocs.io/" target="_blank" rel="noreferrer noopener">documentation</a>.&nbsp; There is also an excellent resource <a href="https://github.com/johnbumgarner/newspaper3_usage_overview" target="_blank" rel="noreferrer noopener">here</a> on GitHub as well.</p>



<p>I have also posted the code for both programs on my <a href="https://github.com/finxter/Articles" target="_blank" rel="noreferrer noopener" title="https://github.com/finxter/Articles">Github page</a> for you to copy if you wish. You can read my follow up article here:</p>



<ul class="wp-block-list"><li><strong>Tutorial</strong>: <a href="https://blog.finxter.com/how-to-generate-a-word-cloud-with-newspaper3k-and-python/" target="_blank" rel="noreferrer noopener" title="How to Generate a Word Cloud with Newspaper3k and Python">How to Set Up a Wordcloud with Newspaper3k</a></li></ul>
<p>The post <a href="https://blog.finxter.com/newspaper3k-a-python-library-for-fast-web-scraping/">Newspaper3k – A Python Library For Fast Web Scraping</a> appeared first on <a href="https://blog.finxter.com">Be on the Right Side of Change</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>

<!--
Performance optimized by W3 Total Cache. Learn more: https://www.boldgrid.com/w3-total-cache/?utm_source=w3tc&utm_medium=footer_comment&utm_campaign=free_plugin

Page Caching using Disk: Enhanced 
Minified using Disk

Served from: blog.finxter.com @ 2026-04-27 11:03:44 by W3 Total Cache
-->