在表格中鍵盤左右鍵不能左右移動(excel表格中鍵盤不能左右移動)
830
2025-03-31
一、背景
對于日常Python爬蟲由于效率問題,本次測試使用多線程和Scrapy框架來實現抓取**斗圖啦**表情。
由于IO操作不使用CPU,對于IO密集(磁盤IO/網絡IO/人機交互IO)型適合用多線程,對于計算密集型:建議用多進程。
進程:
優點:充分利用多核CPU(能夠同時進行多個操作)
缺點:系統資源消耗大,重新開辟內存空間
線程:
優點:共享內存,IO操作可以創造出并發操作
缺點:搶占資源,請求上下文切換消耗時間
但是對于python這種解釋性語言帶有GIL(全局解釋器鎖)解釋器鎖,同一時刻只能有一個線程在運行,遇到IO操作才會釋放切換。感覺沒必要多線程,但是經測試,多線程還是在很大程度能夠提升效率。
二、代碼
git地址
2.1 多線程爬圖
定義了10個線程去爬去每個頁面的具體表情的url存放在類中的img_url_list內,然后通過10個線程從這個列表內取url進行本地圖片下載。
核心代碼
# 定義全局頁面url列表 page_url_list = [] # 定義具體各表情圖片url列表 img_url_list = [] # 定義rlock進程鎖 rlock = threading.RLock() def __init__(self,page_number=10,img_dir='imgdir',thread_number=5): """ :param page_number: 抓去多少個頁面,默認10 :param img_dir: 定義圖片目錄 :param thread_number:默認5個線程 """ self.spider_url = 'https://www.doutula.com/photo/list/?page=' self.page_number = int(page_number) self.img_dir = img_dir self.thread_num = thread_number def __add_urllist(self): """ 定義從page_url_list 爬取具體的image的url :return: """ while True: DutuSpider.rlock.acquire() if len(DutuSpider.page_url_list) == 0: DutuSpider.rlock.release() break else: page_url = DutuSpider.page_url_list.pop() DutuSpider.rlock.release() response = requests.get(page_url, headers=self.__set_header()) soup = BeautifulSoup(response.content,'lxml') sou_list = soup.find_all('img',attrs={'class':'img-responsive lazy image_dta'}) # 將獲取到的具體表情圖標的url保存添加進img_url_list 列表 for url_content in sou_list: DutuSpider.rlock.acquire() DutuSpider.img_url_list.append(url_content['data-original']) DutuSpider.rlock.release() def __download_img(self): """ 從image_url_list中來下載image到本地 :return: """ while True: DutuSpider.rlock.acquire() if len(DutuSpider.img_url_list) == 0: DutuSpider.rlock.release() continue else: img_url = DutuSpider.img_url_list.pop() DutuSpider.rlock.release() try: # 圖片名稱 img_name = img_url.split('/')[-1] # 下載圖片 urllib.urlretrieve(img_url,os.path.join(self.img_dir,img_name)) print('donload img %s' % img_name) except Exception as e: pass def run(self): # 啟動thread_num個進程來爬去具體的img url 鏈接 for th in range(self.thread_num): add_pic_t = threading.Thread(target=self.__add_urllist) add_pic_t.start() # 啟動thread_num個來下載圖片 for img_th in range(self.thread_num): download_t = threading.Thread(target=self.__download_img) download_t.start()
2.2 Scrapy框架爬圖
利用Scrapy框架來爬取表情,items定義圖片名稱和每個圖片的url,scrapy主文件來爬取每個圖片的url來返回,piplines來進行本地文件存儲。
核心代碼
# items,定義img的url和name class ScrapyDoutulaiItem(scrapy.Item): # define the fields for your item here like: # name = scrapy.Field() # 定義圖片url和name img_url = scrapy.Field() img_name = scrapy.Field() # 爬蟲文件 class DoutulaiSpiderSpider(scrapy.Spider): name = 'doutulai_spider' allowed_domains = ['www.doutula.com'] start_urls = ['https://www.doutula.com/photo/list/'] page = 1 def parse(self, response): content_items = ScrapyDoutulaiItem() # 解析img_url列表,拿到圖片的url和,圖片名稱 img_url_list = response.xpath('//img[@class="img-responsive lazy image_dta"]') # page_number = response.xpath('//*[@id="pic-detail"]/div/div[3]/div[3]/ul/li[12]/a/text()').extract_first() page_number = response.xpath('//a[@class="page-link"][last()]/text()').extract_first() for img_content in img_url_list: content_items['img_url'] = img_content.xpath('./@data-original').extract_first() content_items['img_name'] = img_content.xpath('./@data-original').extract_first().split('/')[-1] print(content_items) yield content_items # 不斷爬取新頁面 if self.page <= page_number: self.page += 1 next_url = self.start_urls[0] + '?page=' + str(self.page) yield scrapy.Request(next_url) #pipeline下載圖片 from urllib import urlretrieve from scrapy_doutulai.settings import DOWNLOAD_DIR class ScrapyDoutulaiPipeline(object): def __init__(self): """ 判斷下載目錄是否存在 """ if not os.path.exists(DOWNLOAD_DIR): os.makedirs(DOWNLOAD_DIR) def process_item(self, item, spider): """ 下載圖片 :param item: :param spider: :return: """ try: filename = os.path.join(DOWNLOAD_DIR,item['img_name']) print(filename) urlretrieve(item['img_url'],filename) except Exception as e: pass
三、測試
測試使用2C2G centos7.4,python2.7版本,啟動線程10個,爬去1000頁的表情信息
3.1 多線程測試
啟動爬蟲
nohup doutulai/multithreading_spider/dutulai_spider.py &
查看系統負載
查看文件信息
3.2 Scrapy框架爬圖
啟動爬蟲
nohup doutulai/scrapy_doutulai/scrapy_doutulai/main.py &
查看系統負載
查看文件信息
爬取的圖片
3.3 持久化存儲在OSS上
最終配合阿里云OSS的API來將圖片持久化存儲在對象存儲內。
整體image-:圖片壓縮包
四、總結
經測試自己寫的多線程爬圖,CPU使用率很高,磁盤IO很大。Scrapy默認也是10個線程,但由于自己有磁盤IO操作,CPU使用平穩。
雖然Python有GIL,但是在適當的場景下利用其多線程會很大程度的提升效率。之前如果單線程10分鐘,利用多線程可以縮短3/2的 時間,具體需要結合線程數,磁盤與網絡IO來判斷。
Python Scrapy 任務調度
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。