This error is telling you that your query had no results.
This line:
print(next(res.results).text)
… calls next
on an iterator, res.results
, without a default value:
Retrieve the next item from the iterator by calling its __next__()
method. If default is given, it is returned if the iterator is exhausted, otherwise StopIteration
is raised.
If res
had no results to show you, res.results
is an empty iterator. Meaning it's exhausted right from the start, so when you call next
on it, you're going to get StopIteration
.
And just passing a default isn't going to do much good here. Consider this:
print(next(res.results, None).text)
Now, if there are no results, next
will return your default value None
, and you'll immediately try to do None.text
, which will just raise an AttributeError
.
One way to fix this is to just handle the error:
try:
print(next(res.results).text)
except StopIteration:
print('No results')
Another is to break that compound expression up into simpler ones, so you can use a default:
result = next(res.results, None)
print(res.text if res else 'No results')
However, res
can include 2 or 3 results just as easily as 0—that's the whole reason it returns an iterator. And usually, you're going to want all of them, or at least a few of them. If that's the case, the best solution is to use a for
loop. Iterators are born hoping they'll be used in a for
loop, because it makes everyone's like easier:
for result in res.results:
print(result.text)
This will do nothing if results
is empty, print one result if there's only one, or print all of the results if there are multiple.
If you're worried about getting 500 results when you only wanted a few, you can stop at, say, 3:
for result in itertools.islice(res.results, 3):
print(result.text)
… or:
for i, result in enumerate(res.results):
print(result.text)
if i > 2: break