yield
最近在學習爬蟲,看的是崔慶才作者的書,看到一個關於爬取貓眼電影排行榜的一個程序,其中這個對於爬取下來的html利用正則表達式進行提取的一個函數中
def parse_one_page(html):
pattern = re.compile('<dd>.*?board-index.*?>(\d+)</i>.*?data-src="(.*?)".*?name"><a'
+ '.*?>(.*?)</a>.*?star">(.*?)</p>.*?releasetime">(.*?)</p>'
+ '.*?integer">(.*?)</i>.*?fraction">(.*?)</i>.*?</dd>', re.S)
items = re.findall(pattern, html)
for item in items:
yield {'index': item[0],
'image': item[1],
'title': item[2],
'actor': item[3].strip()[3:],
'time': item[4].strip()[5:],
'score': item[5] + item[6]
}
我並沒有在這個函數中看到return,but
def main(offset):
url = 'http://maoyan.com/board/4?offset=' + str(offset)
html = get_one_page(url)
for item in parse_one_page(html):
print(item)
write_to_file(item)
這裏直接在for循環裏調用了parse_one_page,每次都得到了返回值,最後看到了yield,就查了下用法,看到了廖老師12年寫的解析,寫的很清晰,自己也來記錄下,原帖在這
yield的作用就是把一個函數變成一個 generator,!!點這裏看原帖!!
自己理解的yield
就拿上面的parse_one_page來說,在for循環中,每次調用parse_one_page都會得到一個iterable對象,然後賦給item,然後print。
爲什麼呢?
因爲yield 的作用就是把一個函數變成一個 generator,帶有 yield 的函數不再是一個普通函數,Python 解釋器會將其視爲一個 generator,調用 帶有yield的函數 不會執行此函數,而是返回一個 iterable 對象!在 for 循環執行時,每次循環都會執行 函數內部的代碼,執行到 yield 時,函數就返回一個迭代值,下次迭代時,代碼從 yield 的下一條語句繼續執行,而函數的本地變量看起來和上次中斷執行前是完全一樣的,於是函數繼續執行,直到再次遇到 yield。
爲什麼要用yield
如果在parse_one_page中要用return的話,在爬取內容的數量很多的情況下,該函數在運行中佔用的內存太大,因爲字典太大了,而改用了yield之後,每次迭代中都返回一個數值,佔用內存很小,也很簡潔。