diff --git a/parsel/selector.py b/parsel/selector.py
index bbd4289..666a303 100644
--- a/parsel/selector.py
+++ b/parsel/selector.py
@@ -7,7 +7,7 @@ import sys
 import six
 from lxml import etree, html
 
-from .utils import flatten, iflatten, extract_regex
+from .utils import flatten, iflatten, extract_regex, shorten
 from .csstranslator import HTMLTranslator, GenericTranslator
 
 
@@ -358,6 +358,6 @@ class Selector(object):
     __nonzero__ = __bool__
 
     def __str__(self):
-        data = repr(self.get()[:40])
+        data = repr(shorten(self.get(), width=40))
         return "<%s xpath=%r data=%s>" % (type(self).__name__, self._expr, data)
     __repr__ = __str__
diff --git a/parsel/utils.py b/parsel/utils.py
index 56bb105..458bc6c 100644
--- a/parsel/utils.py
+++ b/parsel/utils.py
@@ -80,4 +80,15 @@ def extract_regex(regex, text, replace_entities=True):
     strings = flatten(strings)
     if not replace_entities:
         return strings
-    return [w3lib_replace_entities(s, keep=['lt', 'amp']) for s in strings]
\ No newline at end of file
+    return [w3lib_replace_entities(s, keep=['lt', 'amp']) for s in strings]
+
+
+def shorten(text, width, suffix='...'):
+    """Truncate the given text to fit in the given width."""
+    if len(text) <= width:
+        return text
+    if width > len(suffix):
+        return text[:width-len(suffix)] + suffix
+    if width >= 0:
+        return suffix[len(suffix)-width:]
+    raise ValueError('width must be equal or greater than 0')

diff --git a/tests/test_selector.py b/tests/test_selector.py
index e504166..c8845a5 100644
--- a/tests/test_selector.py
+++ b/tests/test_selector.py
@@ -133,9 +133,9 @@ class SelectorTestCase(unittest.TestCase):
         body = u"<p><input name='{}' value='\xa9'/></p>".format(50 * 'b')
         sel = self.sscls(text=body)
 
-        representation = "<Selector xpath='//input/@name' data='{}'>".format(40 * 'b')
+        representation = "<Selector xpath='//input/@name' data='{}...'>".format(37 * 'b')
         if six.PY2:
-            representation = "<Selector xpath='//input/@name' data=u'{}'>".format(40 * 'b')
+            representation = "<Selector xpath='//input/@name' data=u'{}...'>".format(37 * 'b')
 
         self.assertEqual(
             [repr(it) for it in sel.xpath('//input/@name')],
diff --git a/tests/test_utils.py b/tests/test_utils.py
new file mode 100644
index 0000000..da20ec2
--- /dev/null
+++ b/tests/test_utils.py
@@ -0,0 +1,26 @@
+from parsel.utils import shorten
+
+from pytest import mark, raises
+import six
+
+
+@mark.parametrize(
+    'width,expected',
+    (
+        (-1, ValueError),
+        (0, u''),
+        (1, u'.'),
+        (2, u'..'),
+        (3, u'...'),
+        (4, u'f...'),
+        (5, u'fo...'),
+        (6, u'foobar'),
+        (7, u'foobar'),
+    )
+)
+def test_shorten(width, expected):
+    if isinstance(expected, six.string_types):
+        assert shorten(u'foobar', width) == expected
+    else:
+        with raises(expected):
+            shorten(u'foobar', width)

Misleading "data=" in Selector representation
Motivation: https://stackoverflow.com/questions/44407581/python-scrapy-output-is-cut-off-hence-wount-let-me-correctly-build-queries

With
```
<Selector xpath='//div[@id="all_game_info"]' data=u'<div id="all_game_info" class="table_wrapper columns'>
```
the user thought that the selector had only extracted `u'<div id="all_game_info" class="table_wrapper columns'`

Suggestions:

* change `data=` to something like `data-preview=`
* or add `...` at the end, indicate the length of extracted data maybe
tests/test_selector.py::SelectorTestCase::test_accessing_attributes tests/test_selector.py::SelectorTestCase::test_bodies_with_comments_only tests/test_selector.py::SelectorTestCase::test_bool tests/test_selector.py::SelectorTestCase::test_boolean_result tests/test_selector.py::SelectorTestCase::test_check_text_argument_type tests/test_selector.py::SelectorTestCase::test_configure_base_url tests/test_selector.py::SelectorTestCase::test_differences_parsing_xml_vs_html tests/test_selector.py::SelectorTestCase::test_dont_strip tests/test_selector.py::SelectorTestCase::test_empty_bodies_shouldnt_raise_errors tests/test_selector.py::SelectorTestCase::test_error_for_unknown_selector_type tests/test_selector.py::SelectorTestCase::test_extending_selector tests/test_selector.py::SelectorTestCase::test_extract_first tests/test_selector.py::SelectorTestCase::test_extract_first_default tests/test_selector.py::SelectorTestCase::test_http_header_encoding_precedence tests/test_selector.py::SelectorTestCase::test_invalid_xpath tests/test_selector.py::SelectorTestCase::test_invalid_xpath_unicode tests/test_selector.py::SelectorTestCase::test_list_elements_type tests/test_selector.py::SelectorTestCase::test_make_links_absolute tests/test_selector.py::SelectorTestCase::test_mixed_nested_selectors tests/test_selector.py::SelectorTestCase::test_namespaces_adhoc tests/test_selector.py::SelectorTestCase::test_namespaces_adhoc_variables tests/test_selector.py::SelectorTestCase::test_namespaces_multiple tests/test_selector.py::SelectorTestCase::test_namespaces_multiple_adhoc tests/test_selector.py::SelectorTestCase::test_namespaces_simple tests/test_selector.py::SelectorTestCase::test_nested_selectors tests/test_selector.py::SelectorTestCase::test_null_bytes_shouldnt_raise_errors tests/test_selector.py::SelectorTestCase::test_pickle_selector tests/test_selector.py::SelectorTestCase::test_pickle_selector_list tests/test_selector.py::SelectorTestCase::test_re tests/test_selector.py::SelectorTestCase::test_re_first tests/test_selector.py::SelectorTestCase::test_re_intl tests/test_selector.py::SelectorTestCase::test_re_replace_entities tests/test_selector.py::SelectorTestCase::test_remove_attributes_namespaces tests/test_selector.py::SelectorTestCase::test_remove_namespaces tests/test_selector.py::SelectorTestCase::test_replacement_char_from_badly_encoded_body tests/test_selector.py::SelectorTestCase::test_replacement_null_char_from_body tests/test_selector.py::SelectorTestCase::test_representation_slice tests/test_selector.py::SelectorTestCase::test_representation_unicode_query tests/test_selector.py::SelectorTestCase::test_select_on_text_nodes tests/test_selector.py::SelectorTestCase::test_select_on_unevaluable_nodes tests/test_selector.py::SelectorTestCase::test_select_unicode_query tests/test_selector.py::SelectorTestCase::test_selector_get_alias tests/test_selector.py::SelectorTestCase::test_selector_getall_alias tests/test_selector.py::SelectorTestCase::test_selector_over_text tests/test_selector.py::SelectorTestCase::test_selectorlist_get_alias tests/test_selector.py::SelectorTestCase::test_selectorlist_getall_alias tests/test_selector.py::SelectorTestCase::test_simple_selection tests/test_selector.py::SelectorTestCase::test_simple_selection_with_variables tests/test_selector.py::SelectorTestCase::test_simple_selection_with_variables_escape_friendly tests/test_selector.py::SelectorTestCase::test_slicing tests/test_selector.py::SelectorTestCase::test_smart_strings tests/test_selector.py::SelectorTestCase::test_text_or_root_is_required tests/test_selector.py::SelectorTestCase::test_weakref_slots tests/test_selector.py::SelectorTestCase::test_xml_entity_expansion tests/test_selector.py::ExsltTestCase::test_regexp tests/test_selector.py::ExsltTestCase::test_set tests/test_utils.py::test_shorten[-1-ValueError] tests/test_utils.py::test_shorten[0-] tests/test_utils.py::test_shorten[1-.] tests/test_utils.py::test_shorten[2-..] tests/test_utils.py::test_shorten[3-...] tests/test_utils.py::test_shorten[4-f...] tests/test_utils.py::test_shorten[5-fo...] tests/test_utils.py::test_shorten[6-foobar] tests/test_utils.py::test_shorten[7-foobar]