日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python教程:使用生成器重构提取数据方法来优化爬虫代码

發布時間:2025/3/20 python 11 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python教程:使用生成器重构提取数据方法来优化爬虫代码 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

在剛開始學習python的時候,有看到過迭代器和生成器的相關內容,不過當時并未深入了解,更談不上使用了

前兩天在網上沖浪時,又看到了幾篇關于生成器的文章,想到之前寫的爬蟲代碼,其實是可以用生成器來改造一下的,所以本次就使用生成器來優化一下爬蟲代碼

我們可以了解到:

  • 生成器函數與普通函數的區別是,生成器用關鍵字 yield 來返回值,而普通函數用 return 一次性返回值;
  • 當你調用生成器函數的時候,函數內部的代碼并不立馬執行 ,這個函數只是返回一個生成器對象;
  • 一般使用for循環迭代生成器對象來獲取具體的返回值

什么時候可以使用生成器呢?

一般爬蟲經常會通過for循環來迭代處理數據,例如我之前爬取20頁數據時,會先把獲得的數據存儲到一個列表或字典中,然后再把整個列表或字典 return 出去,然后保存數據至本地又會再調用這個列表獲取數據(其實做了2步:先把頁面的數據提取出來存到列表,后面用的時候再迭代列表);

類似這種直接使用列表或字典來存儲數據,其實是先存儲到了內存中,如果數據量過大的話,則會占用大量內存,這樣顯然是不合適的;

此時就可以使用生成器,我們每提取一條數據,就把該條數據通過 yield 返回出去,好處是不需要提前把所有數據加載到一個列表中,而是有需要的時候才給它生成值返回,沒調用這個生成器的時候,它就處于休眠狀態等待下一次調用

優化爬蟲代碼

首先看一下未使用生成器的代碼

import requests from requests.exceptions import RequestException import os, time from lxml import etreedef get_html(url):"""獲取頁面內容"""response = requests.get(url, timeout=15)# print(response.status_code)try:if response.status_code == 200:# print(response.text)return response.textelse:return Noneexcept RequestException:print("請求失敗")# return Nonedef parse_html(html_text):"""解析一個結果頁的內容,提取圖片url"""html = etree.HTML(html_text)if len(html) > 0:img_src = html.xpath("//img[@class='photothumb lazy']/@data-original") # 提取圖片url,通過xpath提取會生成一個列表# print(img_src)return img_src # 將提取出來的圖片url列表返回出去else:print("解析頁面元素失敗")def get_all_image_url(depth):"""提取所有頁面的所有圖片url:param depth: 爬取頁碼:return:"""base_url = 'https://imgbin.com/free-png/naruto/' # 定義初始urlimage_urls = []for i in range(1, depth):url = base_url + str(i) # 根據頁碼遍歷請求urlhtml = get_html(url) # 解析每個頁面的內容# print(html)if html:list_data = parse_html(html) # 提取頁面中的圖片urlfor img in list_data:image_urls.append(img)return image_urlsdef get_image_content(url):"""請求圖片url,返回二進制內容"""try:r = requests.get(url, timeout=15)if r.status_code == 200:return r.contentreturn Noneexcept RequestException:return Nonedef main(depth=None):"""主函數,下載圖片:param depth: 爬取頁碼:return:"""j = 1img_urls = get_all_image_url(depth) # 提取頁面中的圖片urlroot_dir = os.path.dirname(os.path.abspath('.'))save_path = root_dir + '/pics/' # 定義保存路徑# print(img_urls)# print(next(img_urls))# print(next(img_urls))# 更多Python相關視頻、資料加群778463939免費獲取for img_url in img_urls: # 遍歷每個圖片urltry:file_path = '{0}{1}.{2}'.format(save_path, str(j), 'jpg')if not os.path.exists(file_path): # 判斷是否存在文件,不存在則爬取with open(file_path, 'wb') as f:f.write(get_image_content(img_url))f.close()print('第{}個文件保存成功'.format(j))else:print("第{}個文件已存在".format(j))j = j + 1except FileNotFoundError as e:print("遇到錯誤:", e)continueexcept TypeError as f:print("遇到錯誤:", f)continueif __name__ == '__main__':start = time.time()main(2)end = time.time()print(end-start)
  • parse_html()函數:它的作用解析一個結果頁的內容,提取一頁的所有圖片url(通過xpath提取,所以數據時存儲在一個列表中),可以把它改造為生成器;

  • get_all_image_url()函數:調用parse_html()函數,通過控制爬取頁碼,提取所有頁面的所有圖片url,然后存到一個列表中返回出去,可以改造為生成器;

  • main()函數:調用get_all_image_url()函數得到所有圖片url的列表,然后迭代這個列表,來得到每一個圖片url來下載圖片

接下來要做的就是改造parse_html()函數 和 get_all_image_url()函數

這個其實也比較簡單,只需要把原本要追加到列表中的東西通過 yield 關鍵字返回出去就行了

parse_html()函數:
def parse_html(html_text):"""解析一個結果頁的內容,提取圖片url"""html = etree.HTML(html_text)if len(html) > 0:img_src = html.xpath("//img[@class='photothumb lazy']/@data-original")# print(img_src)for item in img_src:yield item
get_all_image_url()函數
def get_all_image_url(depth):"""提取所有頁面的所有圖片url:param depth: 爬取頁碼:return:"""#更多Python相關視頻、資料加群778463939免費獲取base_url = 'https://imgbin.com/free-png/naruto/' # 定義初始urlfor i in range(1, depth):url = base_url + str(i) # 根據頁碼遍歷請求urlhtml = get_html(url) # 解析每個頁面的內容# print(html)if html:list_data = parse_html(html) # 提取頁面中的圖片urlfor img in list_data:yield img # 通過yield關鍵字返回每個圖片的url地址

然后上面代碼中有個地方需要注意

1.for i in range(1, depth): 這個for循環,是迭代爬取頁碼

2.list_data = parse_html(html):調用parse_html()函數,獲取每一頁內容的生成器對象

3.for img in list_data: 迭代 list_data,然后通過yield img 把值返回出去

get_all_image_url()函數 還可以用以下方式返回結果

def get_all_image_url(depth):"""提取所有頁面的所有圖片url:param depth: 爬取頁碼:return:"""base_url = 'https://imgbin.com/free-png/naruto/' # 定義初始urlfor i in range(1, depth):url = base_url + str(i) # 根據頁碼遍歷請求urlhtml = get_html(url) # 解析每個頁面的內容# print(html)if html:list_data = parse_html(html) # 提取頁面中的圖片urlyield from list_data

使用關鍵字 yield from 替代了之前的內層for循環,可以達到相同的效果

main()函數 不需要作改動,因為我們在調用生成器對象時,也是通過for循環來提取里面的值的,所以這部分代碼和之前一樣

結尾給大家推薦一個非常好的學習教程,希望對你學習Python有幫助!

Python基礎入門教程推薦:←點擊左邊藍色文字就可以跳轉觀看了

Python爬蟲案例教程推薦:←點擊左邊藍色文字就可以跳轉觀看了

總結

以上是生活随笔為你收集整理的python教程:使用生成器重构提取数据方法来优化爬虫代码的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 真人真事免费毛片 | 国产草草影院 | 日韩手机看片 | 热久久在线 | 午夜精品电影 | 少妇视频网站 | 在线观看av中文字幕 | 伦理片波多野结衣 | 狠狠干免费视频 | 日本中文字幕在线观看 | 国产人妻人伦精品1国产丝袜 | 亚洲精品日韩av | 最全aⅴ番号库 | 欧美日韩成人一区二区三区 | 福利综合网| 免费在线观看一区二区三区 | 亚洲福利在线视频 | 国语对白对话在线观看 | 日韩午夜精品视频 | 欧美男人天堂网 | 播播开心激情网 | 巨胸喷奶水www久久久免费动漫 | 国产123区| 婷婷狠狠干 | 中文字幕久久一区 | 国产黄色的视频 | av一本在线| 日本三不卡 | 亚洲伊人网站 | 精品久久久久成人码免费动漫 | 处女朱莉第一次 | www四虎com| 亚洲视频色 | av成人资源 | 日韩一级影视 | 一级做a爰片久久毛片 | 亚洲乱码精品久久久久 | 国产九色视频 | 青娱乐免费在线视频 | 六月丁香色婷婷 | 欧美日韩一区二区综合 | 久热欧美 | 色呦呦在线视频 | 亚洲精品国产精品国自产观看 | 日本在线三级 | 三年大片在线观看 | 成人亚洲在线 | 狠狠干在线观看 | 一级黄色大毛片 | 少妇无码吹潮 | 国产精品久久久久久影视 | 久久久视频在线观看 | 大尺度摸揉捏胸床戏视频 | 亚洲精品乱码久久久久久不卡 | 一级激情视频 | 国产成人无码AA精品区 | 精品国产乱码久久久久久浪潮 | 天堂√ | 午夜性福利视频 | 久草在现| 日韩av三区 | 米奇影视第四色 | 欧美日韩精品二区 | 在线观看岛国av | 亚洲福利视频网站 | 国产精品成人免费一区久久羞羞 | 国产精品福利小视频 | 超碰在线| 亚洲高清在线 | 免费看黄色片的网站 | 手机av免费在线观看 | 狠狠干狠狠干 | 国产农村乱对白刺激视频 | 国产一区二区99 | proumb性欧美在线观看 | 亚洲制服一区二区 | 绿色地狱在线观看 | 91色视频在线观看 | 免费在线观看一区二区三区 | 欧美乱妇高清无乱码 | 国产麻豆一区二区 | 欧美一级免费大片 | 成人超碰在线 | 日批在线视频 | 日韩手机看片 | 成人免费在线播放视频 | 99嫩草| 国产偷自拍视频 | 久久精品久 | 精品一区二区在线播放 | www精品一区二区三区 | 不卡的av在线 | 亚洲国产剧情在线观看 | 中文字幕乱码亚洲无线三区 | 国产欧美一区二区三区精品酒店 | 国产一二视频 | 精品日本一区二区三区在线观看 | 免费观看毛片 | 色骚综合 |