Scrapy管道爬取图片

        大家好,我是python的初学者,我最近在学习Scrapy管道下载时遇到很多问题,最终虽没有完全克服,但也是收获颇丰,下面我将最近遇到并克服的问题与大家分享一下!

        本文的基础是pycharm,scrapy以及xpath

        首先,先创建scrapy文件夹;

        打开Win+R后输入cmd进入命令提示符。找到你常用的文件夹,这里找到文件夹有两种方法:

1.你可以直接输入文件夹路径名,如:cd+空格+路径                                                                     

2.如果文件名过长那么可以直接找到文件夹,将文件夹直接拖动到 cd+空格后面,效果如下图:

点击回车进入文件夹并创建你的新文件

在文件夹下输入:scrapy startprojec 文件名 网址

需注意的是文件名不能以数字开头,且不能出现中文

 

        回车打开文件进入文件中的spiders文件中,这里我还是建议cd+空格+拖动,因为这种方法确实快,文件夹也不用关闭,后面查看文件也更方便

        在spiders文件夹中创建,输入scrapy  genspider+空格+名字+空格+网址,效果如下

       提前声明:运行spider文件要在命令提示符中输入scrapy  crawl  文件名,在pycharm中是无法运行的。

         创建好后进入文件你可以看到已经创建好的   class  MovieSpider,其中有三个参数分别是:

1.name                                                                                                                                                2.allowed_domains        这个值一般是start_urls去掉http:或者https:后的值,但也有可能是被更改后的值,本次使用的就是电影天堂主页地址去掉http:的值,后面会进行讲解。                              3.start_urls        起始的url,简单易懂    

        在创建spider项目时,我们传入的是电影天堂的首页的url,你可以试试直接传入最新电影页面的url,我传入后文件里的allowed_domains和start_urls的依旧是主页url,而我学习的老师的结果却是传入的url,这个问题至今没解决,可能是版本更新后就是这样,如有解决方法请不吝赐教!

       

         检查Robots协议,先随意在文件中输入一串字符,只要方便查看即可,在命令提示符中输入scrapy  crawl  movie<--(这是我的文件名),如果能看到说明网站不需要遵循robots协议;如果不能输出就进入spiders文件下的settings文件中找到 ROBOTSTXT_OBEY = True,将True改为Flase或者直接Ctrl+/注销掉就好了

        在class下创建方法,我先奉上代码在进行讲解(ps:这只是部分代码,所有代码我在文末上传):

    def parse(self, response):
        # 要第一个的名字和第二个的图片

        a_list = response.xpath('//div[@class="co_content8"]//td[2]//a')

        for a in a_list:
            name = a.xpath('./text()').extract_first()

            href = a.xpath('./@href').extract_first()

            # 第二页的地址是
            url = 'https://www.ygdy8.net' + href

            #     对第二页发起访问
            yield scrapy.Request(url=url, callback=self.parse_second, meta={'name': name})

    def parse_second(self, response):
        # 原本//div[@id="Zoom"]//span/img/@src   span不能加,只能慢慢试
        src = response.xpath('//div[@id="Zoom"]//img/@src').extract_first()
        pic = response.xpath('//div[@id="Zoom"]//img/@src').extract_first()
        # 接受meta参数
        name = response.meta['name']
        movie = ScrapyMovie60Item(src=src, name=name,pic=pic)

        yield movie

        本次爬虫的目的是获取爬取前十页的电影的电影名,图片地址以及下载图片

1.首先进入网页-检索-运用xpath找到我们需要的信息,名字以及下一页的网页,由于大部分是相同的,因此先用a_list接收一部分,从检索中可以看到地址是不完整的,因此用url接收完整的地址。

2.yield的作用与return类似,我们将url传入下一个函数,callback=self.parse_second意思是传入到parse_second,需要注意的是meta是以字典形式传递数据

3.进入parse_second后接收数据,可以看到我的是src和pic的传入是一样的,因为我不仅要图片的网址,还需要下载图片,在后面管道下载时分别下载即可

4.movie是对数据的封装,打开spiders文件下的文件items,输入需要封装的值,名字可以自己取

# Define here the models for your scraped items
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/items.html

import scrapy


class ScrapyMovie60Item(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()

    name=scrapy.Field()
    src=scrapy.Field()
    pic=scrapy.Field()
    pass

只有class下的非注释内容需要自己写;需要注意的是,要使用封装需要传入一段代码在题头,不然会报错,scrapy_movie_60.items 就是之前创建的文件夹名+.items,后面的ScrapyMovie60Item从items文件复制过来就行了,这时候下面不会报错而这里会报错,不用管,能正常使用!

from scrapy_movie_60.items import ScrapyMovie60Item

5.最后返回封装后的yield即可

下面编辑传输管道

进入pipelines文件,提前写入import  urllib.request

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html


# useful for handling different item types with a single interface
import urllib.request

from itemadapter import ItemAdapter


class ScrapyMovie60Pipeline:

    def open_spider(self, spider):
        self.fp = open('movie.json', 'w', encoding='utf-8')

    def process_item(self, item, spider):
        self.fp.write(str(item))
        return item

    def close_spider(self, spider):
        self.fp.close()


class MovieDownloadPipeline:

    def process_item(self, item, spider):
        url = item.get('pic')
        filename = './movie pic/' + item.get('name') + '.jpg'
        urllib.request.urlretrieve(url=url, filename=filename)

        return item

         可见我开启的两条管道,第一条下载名字和图片地址,第二条下载图片

1.第一条管道首先创建了名为movie.json的json文档,然后写入下载文件,最后关闭文件。

2.第二条管道接收到了图片的地址,编辑文件名以及下载到的文件夹,特别说明:movie pic文件夹是我自己创建到spiders下的,如果不提前创建就不会进行下载,最后传值下载即可。

想使用管道还需最后一步:开启管道

进入settings找到 ITEM_PIPELINES,原本就有一条管道,再添加一条下载图片的管道即可

ITEM_PIPELINES = {
   'scrapy_movie_60.pipelines.ScrapyMovie60Pipeline': 300,
   'scrapy_movie_60.pipelines.MovieDownloadPipeline': 301
}

后面的数字是优先级,值越小优先级越高。

此时,已经一切就绪,先奉上所有代码:

movie文件:

import scrapy
from scrapy_movie_60.items import ScrapyMovie60Item


class MovieSpider(scrapy.Spider):
    name = 'movie'
    allowed_domains = ['www.ygdy8.net']
    start_urls = ['https://www.ygdy8.net/html/gndy/dyzz/list_23_1.html']

    base_url = 'https://www.ygdy8.net/html/gndy/dyzz/list_23_'
    page = 1

    def parse(self, response):
        # 要第一个的名字和第二个的图片

        a_list = response.xpath('//div[@class="co_content8"]//td[2]//a')

        for a in a_list:
            name = a.xpath('./text()').extract_first()

            href = a.xpath('./@href').extract_first()

            # 第二页的地址是
            url = 'https://www.ygdy8.net' + href

            #     对第二页发起访问
            yield scrapy.Request(url=url, callback=self.parse_second, meta={'name': name})

    def parse_second(self, response):
        # 原本//div[@id="Zoom"]//span/img/@src   span不能加,只能慢慢试
        src = response.xpath('//div[@id="Zoom"]//img/@src').extract_first()
        pic = response.xpath('//div[@id="Zoom"]//img/@src').extract_first()
        # 接受meta参数
        name = response.meta['name']
        movie = ScrapyMovie60Item(src=src, name=name,pic=pic)

        yield movie

        if self.page < 10:
            self.page = self.page + 1

            url = self.base_url + str(self.page) + '.html'

            # 调用parse方法
            # callback是你要执行的那个方法
            yield scrapy.Request(url=url, callback=self.parse)

其他的上面都有完整的,下面开始运行,在命令提示符spiders文件下输入scrapy crawl movie

这一步我遇到了还未解决的问题

1.例如:报错

 

 2.重复出现

最后可以下载图片205张,有部分下载不了,虽然显示的是路径问题,但是可以下载,应该不是路径问题

 这些问题都未解决,如有头绪,请不吝赐教!

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
首先,你需要安装 scrapy : ```python pip install scrapy ``` 然后,你可以创建一个 scrapy 项目: ```python scrapy startproject beike ``` 进入项目目录,创建一个名为 `beike_spider.py` 的文件,代码如下: ```python import scrapy class BeikeSpider(scrapy.Spider): name = 'beike' allowed_domains = ['bj.ke.com'] start_urls = ['https://bj.ke.com/ershoufang/'] def parse(self, response): img_urls = response.css('.lj-lazy::attr(data-original)').getall() for img_url in img_urls: yield { 'image_urls': [img_url] } ``` 这个爬虫会访问贝壳网二手房页面,提取页面所有图片的链接并返回。你可以通过以下命令来运行这个爬虫: ```python scrapy crawl beike -o images.json ``` 这个命令会把爬取到的图片链接保存到一个名为 `images.json` 的文件。如果你想要下载这些图片,可以在 `settings.py` 文件添加以下配置: ```python ITEM_PIPELINES = {'scrapy.pipelines.images.ImagesPipeline': 1} IMAGES_STORE = 'images' ``` 这个配置会使用 Scrapy 内置的 `ImagesPipeline` 管道来自动下载图片,并把图片保存到 `images` 目录。你可以在 `beike_spider.py` 文件增加以下代码来启用图片下载: ```python class BeikeSpider(scrapy.Spider): # ... def item_completed(self, results, item, info): image_paths = [x['path'] for ok, x in results if ok] if image_paths: item['image_paths'] = image_paths return item ``` 这个代码会在下载完成后自动把图片的路径保存到 `image_paths` 字段。现在你可以通过以下命令来运行这个爬虫下载图片: ```python scrapy crawl beike ``` 这个命令会把下载到的图片保存到 `images/full` 目录

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值