diff --git a/scrapy/http/response/__init__.py b/scrapy/http/response/__init__.py
index e138d5cc8..5b1d34c6d 100644
--- a/scrapy/http/response/__init__.py
+++ b/scrapy/http/response/__init__.py
@@ -55,7 +55,7 @@ class Response(object_ref):
elif body is None:
self._body = ''
else:
- raise TypeError("Response body must either str or unicode. Got: '%s'" \
+ raise TypeError("Response body must either be str or unicode. Got: '%s'" \
% type(body).__name__)
body = property(_get_body, obsolete_setter(_set_body, 'body'))
diff --git a/scrapy/http/response/text.py b/scrapy/http/response/text.py
index 14030d8e5..9a435f194 100644
--- a/scrapy/http/response/text.py
+++ b/scrapy/http/response/text.py
@@ -5,9 +5,12 @@ discovering (through HTTP headers) to base Response class.
See documentation in docs/topics/request-response.rst
"""
+from six.moves.urllib.parse import urljoin
+
from w3lib.encoding import html_to_unicode, resolve_encoding, \
html_body_declared_encoding, http_content_type_encoding
from scrapy.http.response import Response
+from scrapy.utils.response import get_base_url
from scrapy.utils.python import memoizemethod_noargs
@@ -63,6 +66,11 @@ class TextResponse(Response):
self._cached_ubody = html_to_unicode(charset, self.body)[1]
return self._cached_ubody
+ def urljoin(self, url):
+ """Join this Response's url with a possible relative url to form an
+ absolute interpretation of the latter."""
+ return urljoin(get_base_url(self), url)
+
@memoizemethod_noargs
def _headers_encoding(self):
content_type = self.headers.get('Content-Type')
diff --git a/scrapy/utils/response.py b/scrapy/utils/response.py
index 61f43535f..1d79ec0e3 100644
--- a/scrapy/utils/response.py
+++ b/scrapy/utils/response.py
@@ -13,7 +13,6 @@ from twisted.web import http
from twisted.web.http import RESPONSES
from w3lib import html
-from scrapy.http import HtmlResponse, TextResponse
from scrapy.utils.decorator import deprecated
@@ -73,6 +72,7 @@ def open_in_browser(response, _openfunc=webbrowser.open):
"""Open the given response in a local web browser, populating the