Используя scrapy, я пытаюсь загрузить изображение, используя элементы и пользовательский конвейер изображений. Паук должен собрать источник изображения и сохранить его в поле элемента, а затем перейти на следующую страницу, следуя той же ссылке.
Он работает, как и ожидалось, и загружает все изображения, которые мне нужны, называя их стандартным поведением конвейера изображения 'checkum.png'.
Что касается других подобных вопросов, я попытался сделать свой собственный конвейер изображений, перекрывающий некоторые методы, код копирования-вставки, но лучшее, что я получил, - это перетаскиваемый элемент без изображения внутри.
Это неделя, когда я застрял здесь.
pipe.py - беспорядок со всем кодом, который я пробовал до сих пор ...
Спасибо за любую помощь.
В старых вопросах stackoverflow есть код, который больше не действителен из-за устаревших версий, или я мог бы правильно реализовать его в своем проекте.
код паука:
import scrapy
from .. import items
class ImmortaleSpider(scrapy.Spider):
name = 'immortale'
allowed_domains = ['www.mangaeden.com']
start_urls = ['https://www.mangaeden.com/en/it-manga/limmortale/0/1/']
def parse(self, response):
item = items.MangascraperItem()
urls_list = []
name_list = []
for url in response.xpath('//img[@id="mainImg"]/@src').extract():
urls_list.append("https:" + url)
item['image_urls'] = urls_list
name_list.append(response.url.split("/")[-3] + "-" + response.url.split("/")[-2])
item['image_names'] = name_list
yield item
next_page = response.xpath('//a[@class="ui-state-default next"]/@href').extract()
if next_page:
next_href = next_page[0]
next_page_url = response.urljoin(next_href)
request = scrapy.Request(url=next_page_url)
yield request
settings.py:
ITEM_PIPELINES = {
# 'scrapy.pipelines.images.ImagesPipeline': 2,
'mangascraper.pipelines.MyImagesPipeline': 1,
}
IMAGES_STORE = 'images/immortale/'
items.py:
import scrapy
class MangascraperItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
image_urls = scrapy.Field()
images = scrapy.Field()
image_names = scrapy.Field()
pipeline.py:
import scrapy
from scrapy.pipelines.images import ImagesPipeline
from scrapy.exceptions import DropItem
class MyImagesPipeline(ImagesPipeline):
# def get_media_requests(self, item, info):
# for img_url in item['image_urls']:
# # meta = {'filename': item['image_name']}
# meta = {'item':item}
# yield scrapy.Request(url=img_url, meta=meta)
# def file_path(self, request, response=None, info=None):
# return scrapy.Request.meta.get('filename','')
#
# def get_media_requests(self, item, info):
# return [scrapy.Request(url, meta={'filename':item.get('image_name')}) for url in item.get(self.images_urls_field, [])]
# def file_path(self, request, response=None, info=None):
# print "\n" + scrapy.Request.meta['filename'] + "\n"
# return scrapy.Request.meta['filename']
#
# def get_media_requests(self, item, info):
# img_url = item['image_urls'][0]
# meta = {'filename': item['image_names']}
# yield scrapy.Request(url=img_url, meta=meta)
#
# def item_completed(self, results, item, info):
# image_paths = [x['path'] for ok, x in results if ok]
# if not image_paths:
# raise DropItem("Item contains no images")
# item['images'] = image_paths
# return item
def get_media_requests(self, item, info):
for image_url in item['image_urls']:
yield scrapy.Request(url=image_url, meta={'item': item})
#
# def file_path(self, request, response=None, info=None):
# item = scrapy.Request.meta['item']
# image_guid = item['image_names']
# print image_guid
# return 'full/%s.jpg' % (image_guid)
#
def file_path(self, request, response=None, info=None):
image_guid = scrapy.response.url.split("/")[-3] + "-" + response.url.split("/")[-2]
return 'full/%s.jpg' % (image_guid)
# def get_media_requests(self, item, info):
# yield scrapy.Request(item['image_urls'])
def item_completed(self, results, item, info):
image_paths = [x['path'] for ok, x in results if ok]
if not image_paths:
raise DropItem("Item contains no images")
return item
Я ожидал, что мои изображения будут загружены и сохранены с именем файла, хранящимся в поле элемента "image_names", которое заполняется таким образом, чтобы получить формат страницы-главы (1-25,1-26,1-27, 2- 1,2-2 и т. Д.) Для поддержания порядка страниц.
Будет полезно для меня, если у вас есть какая-либо ссылка на рабочий процесс или пошаговое объяснение различных этапов элементов внутри конвейера.
ОБНОВЛЕНИЕ 1: найдено решение с использованием os.rename
pipeline.py:
import scrapy
from scrapy.pipelines.images import ImagesPipeline
from scrapy.utils.project import get_project_settings
import os
class MyImagesPipeline(ImagesPipeline):
IMAGES_STORE = get_project_settings().get("IMAGES_STORE")
def item_completed(self, result, item, info):
image_path = [x["path"] for ok, x in result if ok]
os.rename(self.IMAGES_STORE + "/" + image_path[0], self.IMAGES_STORE + "/full/" + item["image_names"][0] + ".jpg")
return item
# TODO: try to override file_path instead of os.rename