Skip to content

Commit e5bfad5

Browse files
committed
added final test cases, refactored code, modified source, article
1 parent 90e22d7 commit e5bfad5

5 files changed

Lines changed: 58 additions & 48 deletions

File tree

README.rst

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ Newspaper utilizes async io and caching for speed. *Also, everything is in unico
1919

2020
The core 3 methods are:
2121

22-
* ``download()`` retrieves the html, with non blocking io whenever possible.
22+
* ``download()`` retrieves the html, with multithreading whenever possible.
2323
* ``parse()`` extracts the body text, authors, titles, etc from the html.
2424
* ``nlp()`` extracts the summaries, keywords, sentiments from the text.
2525

@@ -29,7 +29,7 @@ There are two API's available. Low level ``article`` objects and ``newspaper`` o
2929
3030
>>> import newspaper
3131
32-
>>> cnn_paper = newspaper.build('http://cnn.com')
32+
>>> cnn_paper = newspaper.build('http://cnn.com') # this takes 10 seconds ish
3333
3434
>>> for article in cnn_paper.articles:
3535
>>> print article.url
@@ -38,25 +38,30 @@ There are two API's available. Low level ``article`` objects and ``newspaper`` o
3838
u'http://www.cnn.com/2013/12/07/us/life-pearl-harbor/?iref=obinsite'
3939
...
4040
41-
>>> print cnn_paper.category_urls
41+
>>> print cnn_paper.size() # number of articles we extracted and cached
42+
3100
43+
44+
# category & feed urls extracted once, then cached for a day (adjustable)
45+
>>> print cnn_paper.category_urls()
4246
[u'http://lifestyle.cnn.com', u'http://cnn.com/world', u'http://tech.cnn.com' ...]
4347
44-
>>> print cnn_paper.feed_urls
48+
>>> print cnn_paper.feed_urls()
4549
[u'http://rss.cnn.com/rss/cnn_crime.rss', u'http://rss.cnn.com/rss/cnn_tech.rss', ...]
4650
4751
48-
#### download html for all articles **concurrently**
49-
>>> cnn_paper.download()
52+
#### build articles, then download, parse, and perform NLP
53+
>>> for article in cnn_paper.articles[:5]:
54+
article.download()
5055
5156
>>> print cnn_paper.articles[0].html
5257
u'<!DOCTYPE HTML><html itemscope itemtype="http://...'
5358
54-
>>> print cnn_paper.articles[5].html
55-
u'<!DOCTYPE HTML><html itemscope itemtype="http://...'
59+
>>> print cnn_paper.articles[7].html
60+
u'' # we only decided to download 5 articles
5661
5762
58-
#### parse html on a per article basis **not concurrent**
59-
>>> cnn_paper.articles[0].parse()
63+
### parse an article for it's body text, top image, authors, and title
64+
>>> cnn_paper.articles[0].parse() # just one article this time
6065
6166
>>> print cnn_paper.articles[0].text
6267
u'Three sisters who were imprisoned for possibly...'
@@ -71,7 +76,7 @@ There are two API's available. Low level ``article`` objects and ``newspaper`` o
7176
u'Police: 3 sisters imprisoned in Tucson home'
7277
7378
74-
#### extract nlp on a per article basis **not concurrent**
79+
#### extract nlp (must be on an already parsed article
7580
>>> cnn_paper.articles[0].nlp()
7681
7782
>>> print cnn_paper.articles[0].summary
@@ -80,22 +85,20 @@ There are two API's available. Low level ``article`` objects and ``newspaper`` o
8085
>>> print cnn_paper.articles[0].keywords
8186
[u'music', u'Tucson', ... ]
8287
88+
# not we try nlp() on an article that has not been downloaded
89+
>>> print cnn_paper.articles[100].nlp()
90+
Traceback (...
91+
...
92+
ArticleException: You must parse an article before you try to nlpify is
93+
8394
8495
#### some other news-source level functionality
8596
>>> print cnn_paper.brand
8697
u'cnn'
8798
88-
## Alternatively, parse and nlp all articles together. Will take a while...
89-
##
90-
## for article in cnn_paper.articles:
91-
## article.parse()
92-
## article.nlp()
93-
##
94-
## You could even download() articles on a per article basis but
95-
## that becomes very slow because it wont be concurrent.
96-
##
97-
## for article in cnn_paper.articles:
98-
## article.download()
99+
>>> print cnn_paper.description
100+
u'CNN.com delivers the latest breaking news and information on the latest...'
101+
99102
100103
Alternatively, you may use newspaper's lower level Article api.
101104

@@ -117,6 +120,12 @@ Alternatively, you may use newspaper's lower level Article api.
117120
>>> print article.authors
118121
[u'Martha Stewart', u'Bob Smith']
119122
123+
>>> print article.top_img
124+
u'http://some.cdn.com/3424hfd4565sdfgdg436/
125+
126+
>>> print article.title
127+
u'Thanksgiving Weather Guide Travel ...'
128+
120129
>>> article.nlp()
121130
122131
>>> print article.summary

newspaper/nlp.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,8 @@ def keywords(text):
118118

119119
import operator # sorting
120120
text = split_words(text)
121-
numWords = len(text) # of words before removing blacklist words
121+
# of words before removing blacklist words
122+
num_words = len(text)
122123
text = [x for x in text if x not in stopwords]
123124
freq = Counter()
124125
for word in text:
@@ -129,7 +130,7 @@ def keywords(text):
129130
keywords = dict((x,y) for x, y in keywords) # recreate a dict
130131

131132
for k in keywords:
132-
articleScore = keywords[k]*1.0 / numWords
133+
articleScore = keywords[k]*1.0 / num_words
133134
keywords[k] = articleScore * 1.5 + 1
134135

135136
keywords = sorted(keywords.iteritems(), key=operator.itemgetter(1))

newspaper/settings.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
PARENT_DIR = os.path.dirname(os.path.abspath(__file__))
1212

13-
POP_URLS_FILEN = os.path.join(PARENT_DIR, 'data/popular_urls.txt')
13+
POP_URLS_FILEN = os.path.join(PARENT_DIR, 'data/popular_sources.txt')
1414
USERAGENTS_FN = os.path.join(PARENT_DIR, 'data/useragents.txt')
1515
STOPWORDS_EN_FN = os.path.join(PARENT_DIR, 'data/stopwords_en.txt')
1616
STOPWORDS_EN_FN_2 = os.path.join(PARENT_DIR, 'data/stopwords_en2.txt')

newspaper/source.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,11 @@ def build(self, parse=True):
7979

8080
# Can not merge category and feed tasks together because
8181
# computing feed urls relies on the category urls!
82-
self.set_category_urls()
82+
self.set_categories()
8383
self.download_categories() # mthread
8484
self.parse_categories()
8585

86-
self.set_feed_urls()
86+
self.set_feeds()
8787
self.download_feeds() # mthread
8888
# self.parse_feeds() # TODO regexing out feeds until fix feedparser!
8989

@@ -96,7 +96,7 @@ def purge_articles(self, reason, in_articles=None):
9696

9797
# TODO TODO Figure out why using the 'del' command on input list reference
9898
# isn't actually filtering the list?!
99-
#cur_articles = self.articles if in_articles is None else in_articles
99+
# cur_articles = self.articles if in_articles is None else in_articles
100100
new_articles = []
101101

102102
for index, article in enumerate(in_articles):
@@ -127,13 +127,13 @@ def _get_category_urls(self, domain):
127127

128128
return parsers.get_category_urls(self)
129129

130-
def set_category_urls(self):
130+
def set_categories(self):
131131
""""""
132132

133133
urls = self._get_category_urls(self.domain)
134134
self.categories = [Category(url=url) for url in urls]
135135

136-
def set_feed_urls(self):
136+
def set_feeds(self):
137137
"""don't need to cache getting feed urls, it's almost
138138
instant w/ xpath"""
139139

@@ -324,7 +324,7 @@ def generate_articles(self, limit=5000):
324324

325325
# log.critical('total', len(articles), 'articles and cutoff was at', limit)
326326

327-
@print_duration
327+
# @print_duration
328328
def download_articles(self, multithread=False):
329329
"""downloads all articles attached to self"""
330330

@@ -378,17 +378,17 @@ def clean_memo_cache(self):
378378

379379
clear_memo_cache(self)
380380

381-
def get_feed_urls(self):
381+
def feed_urls(self):
382382
"""
383383
"""
384384
return [feed.url for feed in self.feeds]
385385

386-
def get_category_urls(self):
386+
def category_urls(self):
387387
"""
388388
"""
389389
return [category.url for category in self.categories]
390390

391-
def get_article_urls(self):
391+
def article_urls(self):
392392
"""
393393
"""
394394

@@ -413,6 +413,6 @@ def print_summary(self):
413413
print '\t[len of html]:', len(a.html)
414414
print '\t=============='
415415

416-
print 'feed_urls:', self.get_feed_urls()
416+
print 'feed_urls:', self.feed_urls()
417417
print '\r\n'
418-
print 'category_urls:', self.get_category_urls()
418+
print 'category_urls:', self.category_urls()

tests/unit_tests.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -167,21 +167,18 @@ def test_source_build(self):
167167
def test_cache_categories(self):
168168
"""builds two same source objects in a row examines speeds of both"""
169169

170-
def wrap_category_urls(source):
171-
source.set_category_urls()
172-
173170
s = Source('http://yahoo.com')
174171
s.download()
175172
s.parse()
173+
s.set_categories()
176174

177-
wrap_category_urls(s)
178-
saved_urls = s.get_category_urls()
175+
saved_urls = s.category_urls()
176+
s.categories = [] # reset and try again with caching
179177

180-
s.category_urls = [] # reset and try again with caching
181-
wrap_category_urls(s)
178+
s.set_categories()
182179

183-
assert sorted(s.get_category_urls()) == sorted(saved_urls)
184-
# print '[CATEGORIES]', s.get_category_urls()
180+
assert sorted(s.category_urls()) == sorted(saved_urls)
181+
# print '[CATEGORIES]', s.category_urls()
185182

186183
class UrlTestCase(unittest.TestCase):
187184
def runTest(self):
@@ -223,6 +220,8 @@ def runTest(self):
223220
print 'testing API unit'
224221
self.test_source_build()
225222
self.test_article_build()
223+
self.test_hot_trending()
224+
self.test_popular_urls()
226225

227226
@print_test
228227
def test_source_build(self):
@@ -243,14 +242,15 @@ def test_article_build(self):
243242

244243
@print_test
245244
def test_hot_trending(self):
246-
"""grab google trending"""
245+
"""grab google trending, just make sure this runs"""
247246

248-
print newspaper.hot()
247+
newspaper.hot()
249248

250249
@print_test
251250
def test_popular_urls(self):
251+
"""just make sure this runs"""
252252

253-
print newspaper.popular_urls()
253+
newspaper.popular_urls()
254254

255255
if __name__ == '__main__':
256256
# unittest.main() # run all units and their cases

0 commit comments

Comments
 (0)