Skip to content

Commit bd96c94

Browse files
author
Xavier Grangier
committed
grangier#137 - refactor title extraction based on opengraph, meta headling and title element
1 parent 66b63fc commit bd96c94

1 file changed

Lines changed: 56 additions & 30 deletions

File tree

goose/extractors.py

Lines changed: 56 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
MOTLEY_REPLACEMENT = StringReplacement("�", "")
3131
ESCAPED_FRAGMENT_REPLACEMENT = StringReplacement(u"#!", u"?_escaped_fragment_=")
3232
TITLE_REPLACEMENTS = ReplaceSequence().create(u"»").append(u"»")
33+
TITLE_SPLITTERS = [u"|", u"-", u"»", u":"]
3334
PIPE_SPLITTER = StringSplitter("\\|")
3435
DASH_SPLITTER = StringSplitter(" - ")
3536
ARROWS_SPLITTER = StringSplitter("»")
@@ -65,44 +66,69 @@ def __init__(self, config, article):
6566
# stopwords class
6667
self.stopwords_class = config.stopwords_class
6768

69+
def clean_title(self, title):
70+
"""Clean title with the use of og:site_name
71+
in this case try to get ride of site name
72+
and use TITLE_SPLITTERS to reformat title
73+
"""
74+
# check if we have the site name in opengraph data
75+
if "site_name" in self.article.opengraph.keys():
76+
site_name = self.article.opengraph['site_name']
77+
# remove the site name from title
78+
title = title.replace(site_name, '').strip()
79+
80+
# try to remove the domain from url
81+
if self.article.domain:
82+
pattern = re.compile(self.article.domain, re.IGNORECASE)
83+
title = pattern.sub("", title).strip()
84+
85+
# split the title in words
86+
# TechCrunch | my wonderfull article
87+
# my wonderfull article | TechCrunch
88+
title_words = title.split()
89+
90+
# check if first letter is in TITLE_SPLITTERS
91+
# if so remove it
92+
if title_words[0] in TITLE_SPLITTERS:
93+
title_words.pop(0)
94+
95+
# check if last letter is in TITLE_SPLITTERS
96+
# if so remove it
97+
if title_words[-1] in TITLE_SPLITTERS:
98+
title_words.pop(-1)
99+
100+
# rebuild the title
101+
title = u" ".join(title_words).strip()
102+
103+
return title
104+
68105
def get_title(self):
69106
"""\
70107
Fetch the article title and analyze it
71108
"""
72-
73109
title = ''
74-
doc = self.article.doc
75110

76-
title_element = self.parser.getElementsByTag(doc, tag='title')
77-
# no title found
78-
if title_element is None or len(title_element) == 0:
79-
return title
111+
# rely on opengraph in case we have the data
112+
if "title" in self.article.opengraph.keys():
113+
title = self.article.opengraph['title']
114+
return self.clean_title(title)
80115

81-
# title elem found
82-
title_text = self.parser.getText(title_element[0])
83-
used_delimeter = False
84-
85-
# split title with |
86-
if '|' in title_text:
87-
title_text = self.split_title(title_text, PIPE_SPLITTER)
88-
used_delimeter = True
89-
90-
# split title with -
91-
if not used_delimeter and '-' in title_text:
92-
title_text = self.split_title(title_text, DASH_SPLITTER)
93-
used_delimeter = True
94-
95-
# split title with »
96-
if not used_delimeter and u'»' in title_text:
97-
title_text = self.split_title(title_text, ARROWS_SPLITTER)
98-
used_delimeter = True
99-
100-
# split title with :
101-
if not used_delimeter and ':' in title_text:
102-
title_text = self.split_title(title_text, COLON_SPLITTER)
103-
used_delimeter = True
116+
# try to fetch the meta headline
117+
meta_headline = self.parser.getElementsByTag(
118+
self.article.doc,
119+
tag="meta",
120+
attr="name",
121+
value="headline")
122+
if meta_headline is not None and len(meta_headline) > 0:
123+
title = self.parser.getAttribute(meta_headline[0], 'content')
124+
return self.clean_title(title)
125+
126+
# otherwise use the title meta
127+
title_element = self.parser.getElementsByTag(self.article.doc, tag='title')
128+
if title_element is not None and len(title_element) > 0:
129+
title = self.parser.getText(title_element[0])
130+
return self.clean_title(title)
104131

105-
title = MOTLEY_REPLACEMENT.replaceAll(title_text)
106132
return title
107133

108134
def split_title(self, title, splitter):

0 commit comments

Comments
 (0)