Downloads HTML <head> tag first, extracts data from it using
        specific head techniques, loads it and checks if is complete. 
        Otherwise downloads the HTML <body> tag as well and loads data 
        extracted by using appropriate semantic techniques.

        Eagerly calls check_url(url) if any, before parsing the HTML.
        Provided function should raise an exception to break extraction.
        E.g.: URL has been summarized before; URL points to off limits
        websites like foursquare.com, facebook.com, bitly.com and so on.

def extract(self, check_url=None, http_equiv_refresh=True):
        """
        Downloads HTML <head> tag first, extracts data from it using
        specific head techniques, loads it and checks if is complete. 
        Otherwise downloads the HTML <body> tag as well and loads data 
        extracted by using appropriate semantic techniques.

        Eagerly calls check_url(url) if any, before parsing the HTML.
        Provided function should raise an exception to break extraction.
        E.g.: URL has been summarized before; URL points to off limits
        websites like foursquare.com, facebook.com, bitly.com and so on.
        """
        # assert self._is_clear()
        logger = logging.getLogger(__name__)
        logger.info("Extract: %s", self.clean_url)
        with closing(request.get(self.clean_url, stream=True)) as response:
            response.raise_for_status()
            mime = response.headers.get('content-type')
            if mime and not ('html' in mime.lower()):
                raise HTMLParseError('Invalid Content-Type: %s' % mime)
            self.clean_url = self._clean_url(response.url)
            if self.clean_url is None:
                raise URLError('Bad url: %s' % response.url)
            if check_url is not None:
                check_url(url=self.clean_url)

            encoding = config.ENCODING or response.encoding

            self._html = ""
            if config.PHANTOMJS_BIN and \
                site(self.clean_url) in config.PHANTOMJS_SITES:
                self._html = request.phantomjs_get(self.clean_url)
                response.consumed = True

            head = self._get_tag(response, tag_name="head", encoding=encoding)

            if http_equiv_refresh:
                # Check meta http-equiv refresh tag
                html = head or decode(self._html, encoding)
                self._extract(html, self.clean_url, [
                    "summary.techniques.HTTPEquivRefreshTags",
                ])
                new_url = self.urls and self.urls[0]
                if new_url and new_url != self.clean_url:
                    logger.warning("Refresh: %s", new_url)
                    self._clear()
                    self.clean_url = new_url
                    return self.extract(check_url=check_url, http_equiv_refresh=False)

            if head:
                logger.debug("Got head: %s", len(head))
                self._extract(head, self.clean_url, [
                    "extraction.techniques.FacebookOpengraphTags",
                    "extraction.techniques.TwitterSummaryCardTags",
                    "extraction.techniques.HeadTags"
                ])
            else:
                logger.debug("No head: %s", self.clean_url)

            if config.GET_ALL_DATA or not self._is_complete():
                body = self._get_tag(response, tag_name="body", encoding=encoding)
                if body:
                    logger.debug("Got body: %s", len(body))
                    self._extract(body, self.clean_url, [
                        "extraction.techniques.HTML5SemanticTags",
                        "extraction.techniques.SemanticTags"                
                    ])
                else:
                    logger.debug("No body: %s", self.clean_url)

            if not head and not body:
                raise HTMLParseError('No head nor body tags found.')

            del self._html