爬蟲4-Pipline image(下載圖片)


1.pipline:

翻成中文其實就是管道的意思,把資料想像成是管道裡的水,你把資料導流到你建設好的洪池,也就是自己定義的Class 裡面,但含式的名字只能複寫喔,無法做到自訂義喔

在複寫pipline有幾個函式須注意:

a.我們必須設定Setting的部分:

ITEM_PIPELINES = {
    'myproject.pipelines.MyImagesPipeline': 300
}
IMAGES_STORE = os.getcwd()+"/comics"

如果沒有特別定義路徑的話,資料會直接在Current path 流進來

b.get_media_requests(對url發出request):

在main spider class 使用yield 資料將會第一手跑來這裡發出request:

import scrapy
from itemadapter import ItemAdapter
from scrapy.exceptions import DropItem
from scrapy.pipelines.images import ImagesPipeline
class MyImagesPipeline(ImagesPipeline):

	def get_media_requests(self, item, info):
		for image_urlin item['image_urls']:
			yield scrapy.Request(image_url)
		
	def item_completed(self, results, item, info):
			image_paths = [x['path']for ok, xin resultsif ok]
			if not image_paths:
					raise DropItem("Item contains no images")
	    adapter = ItemAdapter(item)
	    adapter['image_paths'] = image_paths
			return item

c.file_path(定義路徑):

import os
from urllib.parse import urlparse

from scrapy.pipelines.images import ImagesPipeline

class MyImagesPipeline(ImagesPipeline):

    def file_path(self, request, response=None, info=None, *, item=None):
        return 'files/' + os.path.basename(urlparse(request.url).path))

在這邊你可以定義下載路徑,

d.item_completed(下載完後要的事情):

我看官方文件意思應該是,當下載完成後要做的事情(這邊我沒有實際運到這裡,以後如果有用到會再來更新)

PS:有時下載圖片會失敗,需重新安裝

pip install --no-cache-dir -I pillow

2.urlib + open:

import urllib
import urllib.request
import zlib

def save_img(self, img_mun, title, img_url):
	# 将图片保存到本地
	
	self.log('saving pic: ' + img_url)
	
	# 保存漫画的文件夹
	
	document = '/'
	
	# 每部漫画的文件名以标题命名
	
	comics_path = document + '/' + title
	
	exists = os.path.exists(comics_path)
	
	if not exists:
	
	self.log('create document: ' + title)
	
	os.makedirs(comics_path)
	
	# 每张图片以页数命名
	
	pic_name = comics_path + '/' + img_mun
	
	# 检查图片是否已经下载到本地,若存在则不再重新下载
	
	exists = os.path.exists(pic_name)
	
	if exists:
	
	self.log('pic exists: ' + pic_name)
	
	return
	
	try:
	
	user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
	
	headers = {'User-Agent': user_agent}
	
	req = urllib.request.Request(img_url, headers=headers)
	
	response = urllib.request.urlopen(req, timeout=30)
	
	# 请求返回到的数据
	
	data = response.read()
	
	# 若返回数据为压缩数据需要先进行解压
	
	if response.info().get('Content-Encoding') == 'gzip':
	
	data = zlib.decompress(data, 16 + zlib.MAX_WBITS)
	
	# 图片保存到本地
	
	fp = open(pic_name, "wb")
	
	fp.write(data)
	
	fp.close
	
	self.log('save image finished:' + pic_name)
	
	except Exception as e:
	
	self.log('save image error.')
	
	self.log(e)

我們利用urlib 可以用開啟圖片的url 並且配合 open 的function把它存到對應的路徑去喔,雖然不符合scrapy的存圖片方式,但也是個方法啦

**優點:**可以快速自訂義拿取圖片的方法 **缺點:**需知道一些發request的知識








留言

這個網誌中的熱門文章

Vue那些我踩過的坑(Vuex-TypeScript)

Vue(Vue3取代 Vuex?)

前端優化效能-1(lazy-img)