爬蟲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的知識
留言
張貼留言