diff --git a/.gitignore b/.gitignore index 3d20afb1..0b9c4f9f 100644 --- a/.gitignore +++ b/.gitignore @@ -40,3 +40,4 @@ nosetests.xml .project .pydevproject venv +Pipfile* diff --git a/newspaper/extractors.py b/newspaper/extractors.py index 96255401..ed5964cc 100644 --- a/newspaper/extractors.py +++ b/newspaper/extractors.py @@ -820,13 +820,22 @@ def calculate_best_node(self, doc): if parent_node not in parent_nodes: parent_nodes.append(parent_node) - # Parent of parent node - parent_parent_node = self.parser.getParent(parent_node) - if parent_parent_node is not None: - self.update_node_count(parent_parent_node, 1) - self.update_score(parent_parent_node, upscore / 2) - if parent_parent_node not in parent_nodes: - parent_nodes.append(parent_parent_node) + # Issue 645, 776 - Some text was left out due to "deep" nodes + # containing content not being accounted for. This should result + # in the "heaviest" content subtree as the "top node." + # + # Percolate weights up through the tree. Not really sure + # what the upscore is, but seems that it should decay, so + # decaying linearly. + ancestor_node = self.parser.getParent(parent_node) + j = 2 + while ancestor_node is not None: + self.update_score(ancestor_node, upscore / (float(j))) + if ancestor_node not in parent_nodes: + parent_nodes.append(ancestor_node) + ancestor_node = self.parser.getParent(ancestor_node) + j += 1 + cnt += 1 i += 1 diff --git a/newspaper/parsers.py b/newspaper/parsers.py index a4d030c0..1c554a8b 100644 --- a/newspaper/parsers.py +++ b/newspaper/parsers.py @@ -7,8 +7,11 @@ or query an lxml or soup dom object generated from an article's html. """ import logging +import traceback + import lxml.etree import lxml.html +import lxml.html.soupparser import lxml.html.clean import re from html import unescape @@ -65,10 +68,17 @@ def fromstring(cls, html): # lxml does not play well with encoding tags if html.startswith('', '', html, flags=re.DOTALL) - cls.doc = lxml.html.fromstring(html) + root = lxml.html.fromstring(html) + try: + ignore = lxml.html.tostring(root, encoding='unicode') + cls.doc = root + except UnicodeDecodeError: + cls.doc = lxml.html.soupparser.fromstring(html, None, None, features='html5lib') return cls.doc - except Exception: - log.warn('fromstring() returned an invalid string: %s...', html[:20]) + except Exception as e: + tb = traceback.format_exc() + log.warn('fromstring() returned an invalid string (%s): %s...', str(e), html[:20]) + log.warn(tb) return @classmethod diff --git a/requirements.txt b/requirements.txt index 61974601..b225d10b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,4 +11,5 @@ python-dateutil>=2.5.3 PyYAML>=3.11 requests>=2.10.0 tinysegmenter==0.3 # TODO(codelucas): Investigate making this >=0.3 -tldextract>=2.0.1 \ No newline at end of file +tldextract>=2.0.1 +html5lib>=1.1