【问题标题】:Scrapy Images DownloadingScrapy 图像下载
【发布时间】:2016-08-04 16:22:24
【问题描述】:

我的蜘蛛运行没有显示任何错误,但图像没有存储在文件夹中这是我的scrapy文件:

Spider.py:

import scrapy
import re
import os
import urlparse
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
from scrapy.loader.processors import Join, MapCompose, TakeFirst
from scrapy.pipelines.images import ImagesPipeline
from production.items import ProductionItem, ListResidentialItem

class productionSpider(scrapy.Spider):
    name = "production"
    allowed_domains = ["someurl.com"]
    start_urls = [
        "someurl.com"
]

def parse(self, response):
    for sel in response.xpath('//html/body'):
        item = ProductionItem()
        img_url = sel.xpath('//a[@data-tealium-id="detail_nav_showphotos"]/@href').extract()[0]
        yield scrapy.Request(urlparse.urljoin(response.url, img_url),callback=self.parseBasicListingInfo,  meta={'item': item})

def parseBasicListingInfo(item, response):
    item = response.request.meta['item']
    item = ListResidentialItem()
    try:
        image_urls = map(unicode.strip,response.xpath('//a[@itemprop="contentUrl"]/@data-href').extract())
        item['image_urls'] = [ x for x in image_urls]
    except IndexError:
        item['image_urls'] = ''

    return item

settings.py:

from scrapy.settings.default_settings import ITEM_PIPELINES
from scrapy.pipelines.images import ImagesPipeline

BOT_NAME = 'production'

SPIDER_MODULES = ['production.spiders']
NEWSPIDER_MODULE = 'production.spiders'
DEFAULT_ITEM_CLASS = 'production.items'

ROBOTSTXT_OBEY = True
DEPTH_PRIORITY = 1
IMAGE_STORE = '/images'

CONCURRENT_REQUESTS = 250

DOWNLOAD_DELAY = 2

ITEM_PIPELINES = {
    'scrapy.contrib.pipeline.images.ImagesPipeline': 300,
}

items.py

# -*- coding: utf-8 -*-
import scrapy

class ProductionItem(scrapy.Item):
    img_url = scrapy.Field()

# ScrapingList Residential & Yield Estate for sale
class ListResidentialItem(scrapy.Item):
    image_urls = scrapy.Field()
    images = scrapy.Field()

    pass

我的管道文件是空的,我不确定要添加到 pipeline.py 文件中的内容。

非常感谢任何帮助。

【问题讨论】:

    标签: python image scrapy


    【解决方案1】:

    在我的例子中,是 IMAGES_STORE 路径导致了问题

    我做了IMAGES_STORE = 'images',它就像一个魅力!

    完整代码如下:

    设置:

    ITEM_PIPELINES = {
       'mutualartproject.pipelines.MyImagesPipeline': 1,
    }
    
    IMAGES_STORE = 'images' 
    

    管道:

    class MyImagesPipeline(ImagesPipeline):
    
        def get_media_requests(self, item, info):
            for image_url in item['image_urls']:
                yield scrapy.Request(image_url)
    
        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
    

    【讨论】:

      【解决方案2】:

      我的工作最终结果:

      spider.py

      import scrapy
      import re
      import urlparse
      from scrapy.spiders import CrawlSpider, Rule
      from scrapy.linkextractors import LinkExtractor
      from scrapy.loader.processors import Join, MapCompose, TakeFirst
      from scrapy.pipelines.images import ImagesPipeline
      from production.items import ProductionItem
      from production.items import ImageItem
      
      class productionSpider(scrapy.Spider):
          name = "production"
          allowed_domains = ["url"]
          start_urls = [
              "startingurl.com"
          ]
      
      def parse(self, response):
          for sel in response.xpath('//html/body'):
              item = ProductionItem()
              img_url = sel.xpath('//a[@idd="followclaslink"]/@href').extract()[0]
              yield scrapy.Request(urlparse.urljoin(response.url, img_url),callback=self.parseImages,  meta={'item': item})
      
      def parseImages(self, response):
          for elem in response.xpath("//img"):
              img_url = elem.xpath("@src").extract_first()
              yield ImageItem(image_urls=[img_url])
      

      Settings.py

      BOT_NAME = 'production'
      
      SPIDER_MODULES = ['production.spiders']
      NEWSPIDER_MODULE = 'production.spiders'
      DEFAULT_ITEM_CLASS = 'production.items'
      ROBOTSTXT_OBEY = True
      IMAGES_STORE = '/Users/home/images'
      
      DOWNLOAD_DELAY = 2
      
      ITEM_PIPELINES = {'scrapy.pipelines.images.ImagesPipeline': 1}
      # Disable cookies (enabled by default)
      

      items.py

      # -*- coding: utf-8 -*-
      import scrapy
      
      class ProductionItem(scrapy.Item):
          img_url = scrapy.Field()
      # ScrapingList Residential & Yield Estate for sale
      class ListResidentialItem(scrapy.Item):
          image_urls = scrapy.Field()
          images = scrapy.Field()
      
      class ImageItem(scrapy.Item):
          image_urls = scrapy.Field()
          images = scrapy.Field()
      

      pipelines.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 image_url in item['image_urls']:
                  yield scrapy.Request(image_url)
      
          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['image_paths'] = image_paths
              return item
      

      【讨论】:

        【解决方案3】:

        由于您不知道要在管道中放入什么,我假设您可以对 scrapy 提供的图像使用默认管道,因此在 settings.py 文件中您可以像这样声明它

        ITEM_PIPELINES = {
        'scrapy.pipelines.images.ImagesPipeline':1
        }
        

        另外,你的图片路径是错误的/ 意味着你要去你机器的绝对根路径,所以你要么把绝对路径放在你想保存的地方,要么只是从你的地方做一个相对路径正在运行你的爬虫

        IMAGES_STORE = '/home/user/Documents/scrapy_project/images'
        

        IMAGES_STORE = 'images'
        

        现在,在蜘蛛中,您提取 url 但您没有将其保存到项目中

        item['image_urls'] = sel.xpath('//a[@data-tealium-id="detail_nav_showphotos"]/@href').extract_first()
        

        如果您使用的是默认管道,则该字段必须是 image_urls

        现在,在items.py 文件中,您需要添加以下 2 个字段(这两个字段都需要使用此文字名称)

        image_urls=Field()
        images=Field()
        

        应该可以的

        【讨论】:

        • 谢谢 Rafael,但是仍然没有图像填充图像文件夹,我将管道添加到 settings.py 文件。更改了存储路径并更改了以下行 image_urls = map(unicode.strip,response.xpath('//a[@itemprop="contentUrl"]/@data-href').extract()) item['image_urls' ] = [ x for x in image_urls] to item['image_urls'] = map(unicode.strip,response.xpath('//a[@itemprop="contentUrl"]/@data-href').extract() )
        • 你不能映射图像,如果你想在一个项目中保存多个图像,你必须创建一个数组而不是一个地图,这是行不通的
        • 我对这一切都很陌生,我尝试通过将其更改为这个来修复它? item['image_urls'] = response.xpath('//a[@itemprop="contentUrl"]/@data-href').extract()[0] [0] 应该只给出一张图片,但它仍然没有'不出现我仍然缺少什么还是它仍然是一个数组?
        • 你应该 yield item 而不是 return item 就像请求一样
        • 抱歉 Rafael 花费了这么多时间,仍然无法下载图像。该文件夹仍然是空的,没有错误,但不应该在代码中的某处调用 image = scrapy.field() 吗?
        【解决方案4】:

        只是在这里添加我的错误,这让我花了几个小时。也许它可以帮助某人。

        来自 scrapy 文档 (https://doc.scrapy.org/en/latest/topics/media-pipeline.html#using-the-images-pipeline):

        然后,将目标存储设置配置为将用于存储下载图像的有效值。 否则管道将保持禁用状态,即使您将其包含在 ITEM_PIPELINES 设置中也是如此。

        出于某种原因,我使用了冒号“:”而不是等号“=”。

            # My misstake:
            IMAGES_STORE : '/Users/my_user/images'
        
            # Working code
            IMAGES_STORE = '/Users/my_user/images'
        

        这不会返回错误,而是会导致管道根本无法加载,这对我来说很难解决。

        【讨论】:

          【解决方案5】:

          您必须在 settings.py 文件中启用 SPIDER_MIDDLEWARES 和 DOWNLOADER_MIDDLEWARES

          【讨论】:

            猜你喜欢
            • 2018-12-15
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-02-06
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多