举例
要求抓取城市气温信息并依此显示。
传统方法是直接抓取所有城市信息保存在字典中,然后循环遍历打印出结果。但是这种方法的缺点是:由于是网络抓取,可能网络开销比较大。当抓取量比较大的时候,程序给用户的感觉可能是卡住,过半天显示第一条信息。
实现思路
采用“用时访问”的策略,抓取一条显示一条。并且封装到一个对象里,用for语句进行迭代。
首先实现一个迭代器对象,next方法每次返回一个城市的气温。
然后实现一个可迭代对象,__iter__
方法返回一个迭代器对象。
实现
首先实现一个获取城市气温的程序:
# -*- coding: utf-8 -*-
import requests
def getWeather(city):
r = requests.get(u'http://wthrcdn.etouch.cn/weather_mini?city=' + city)
data = r.json()['data']['forecast'][0]
return '%s: %s, %s' % (city, data['low'], data['high'])
print getWeather(u'北京')
print getWeather(u'深圳')
使用requests对一个固定网址进行get请求,最终对得到的json数据进行解析得到结果。
对上面的程序进行改造,程序如下:
# -*- coding: utf-8 -*-
import requests
from collections import Iterable, Iterator
class WeatherIterabor(Iterator):
def __init__(self, cities):
self.cities = cities
self.index = 0
def getWeather(self, city):
r = requests.get(u'http://wthrcdn.etouch.cn/weather_mini?city=' + city)
data = r.json()['data']['forecast'][0]
return '%s: %s, %s' % (city, data['low'], data['high'])
def next(self):
if self.index == len(self.cities):
raise StopIteration
city = self.cities[self.index]
self.index += 1
return self.getWeather(city)
class WeathrerIterable(Iterable):
def __init__(self, cities):
self.cities = cities
def __iter__(self):
return WeatherIterabor(self.cities)
for x in WeathrerIterable([u'北京', u'上海', u'西安', u'齐齐哈尔', u'厦门', u'广州', u'香港', u'深圳', u'呼和浩特']):
print x