Chapter 9.3 项目练习-下载image

9.3 项目实战:下载360图片

  下面来完成一个使用ImagesPipeline下载图片的实战项目。360图片是一个知名的图片搜索网站,在浏览器中打开http://image.so.com,页面如图9.3-1所示。
图9.3-1

图9.3-1
  其中,汽车分类下有大量字画图片,我们可以编写爬虫爬取这些图片。 其中,汽车分类下有大量字画图片,我们可以编写爬虫爬取这些图片。 ![图9.3-2](https://img-blog.csdnimg.cn/882a8e1ae5eb49ee81edeca815cec180.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAbGVlJ3Mgd29yaw==,size_20,color_FFFFFF,t_70,g_se,x_16)
图9.3-2

9.3.1 项目需求

  下载360图片网站中汽车分类下的所有图片到本地。

9.3.2 页面分析

  在图9.3-1所示的页面中向下滚动鼠标滚轮,便会有更多图片加载出来,图片加载是由JavaScript脚本完成的,在图9.3.2-1中可以看到jQuery发送的请求,其响应结果是一个json串。
图9.3.2-1

图9.3.2-1

  复制图中jQuery发送请求的url,使用scrapy shell进行访问,查看响应结果的内容(json):

$ (Scrapy_env) so_image>scrapy shell https://image.so.com/zjl?ch=car&listtype=new&sn=30
...
[s] Available Scrapy objects:
[s]   scrapy     scrapy module (contains scrapy.Request, scrapy.Selector, etc)
[s]   crawler    <scrapy.crawler.Crawler object at 0x000001A664818310>
[s]   item       {}
[s]   request    <GET https://image.so.com/zjl?ch=car>
[s]   response   <200 https://image.so.com/zjl?ch=car>
[s]   settings   <scrapy.settings.Settings object at 0x000001A664815DF0>
[s]   spider     <DefaultSpider 'default' at 0x1a664bdd520>
[s] Useful shortcuts:
[s]   fetch(url[, redirect=True]) Fetch URL and update local objects (by default, redirects are followed)
[s]   fetch(req)                  Fetch a scrapy.Request and update local objects
[s]   shelp()           Shell help (print this help)
[s]   view(response)    View response in a browser

>>> response
<200 https://image.so.com/zjl?ch=car>
>>> import json
>>> res =json.loads(response.body.decode('utf-8'))
>>> res
{'end': False, 
'count': 30, 
'lastid': 30, 
'prevsn': '0', 
'list': [{
'id': 'f5661fd288648a3f07161687b66575ca', 
'index': 1, 
'grpmd5': '7544f034562ec9531b290745fe82266f', 
'grpseq': '1', 
'grpcnt': '1', 
'imgkey': 't0108d75cea79237c90.jpg', 
'width': '1024', 
'height': '768', 
'title': '【美车致】未来科技 Rinspeed Etos', 
'imgurl': 'http://img1c.xgo-img.com.cn/pics/2547/2546478.jpg', 
'purl': 'http://photo.58che.com/car/14285_2546478.html', 
'site': 'photo.58che.com', 
'imgsize': '0', 
'label': '概念车', 
'sitename': '58che.com', 
'siteid': '11943280',
 'src': '0', 
 'fnum': '0', 
 'qhimg_thumb_width': 200, 
 'qhimg_thumb_height':150, 
 'qhimg_downurl': 'https://dl.image.so.com/dimgurl=https%3A%2F%2Fp0.ssl.qhimgs1.com%2Ft0108d75cea79237c90.jpg&purl=https%3A%2F%2Fimage.so.com%2F%3Fsrc%3Ddl.image&key=d825af2f3c', 
 'qhimg_url': 'https://p0.ssl.qhimgs1.com/t0108d75cea79237c90.jpg', 
 'qhimg_thumb': 'https://p0.ssl.qhimgs1.com/sdr/200_200_/t0108d75cea79237c90.jpg', 'qhimg_qr_key': 'b8887e3c5f', 
 'tag':'0', 
 'rdate': '1502943765', 
 'ins_time': '2017-08-17 12:22:45',
  'dsptime': '', 
  'summary': [], 
  'pic_desc': ' 【美车致】未来科技 Rinspeed Etos'}, 
...省略
{'id': '14075fea0b788704778180d964a74433', 
'index': 30, 'grpmd5': 'c326588444a6a6abfa4938e415e587ac',
 'grpseq': '1', 
 'grpcnt': '1', 
 'imgkey': 't0123e59e97f75e03c4.jpg', 
 'width': '1600', 
 'height': '1200', 
 'title': '宝马旅行版概念车', 
 'imgurl': 'http://img1b.xgo-img.com.cn/pics/1521/1520902.jpg', 
 'purl': 'http://photo.58che.com/car/10398_1520902.html', 
 'site': 'photo.58che.com', 
 'imgsize': '0',
 'label': '概念车', 
 'sitename': '58che.com', 
 'siteid': '11943280', 
 'src': '0', 
 'fnum': '0', 
 'qhimg_thumb_width': 200, 
 'qhimg_thumb_height': 150, 
 'qhimg_downurl': 'https://dl.image.so.com/d宝马旅行版概念车', 
 'imgurl': 'http://img1b.xgo-img.com.cn/pics/1521/1520902.jpg',
 'purl':'http://photo.58che.com/car/10398_1520902.html',
 'site': 'photo.58che.com', 
 'imgsize': '0', 
 'label': '概念车', 
 'sitename': '58che.com', 
 'siteid': '11943280', 
 'src': '0', 
 'fnum': '0', 
 'qhimg_thumb_width': 200, 
 'qhimg_thumb_height': 150, 
 'qhimg_downurl': 'https://dl.image.so.com/dimgurl=https%3A%2F%2Fp0.ssl.qhimgs1.com%2Ft0123e59e97f75e03c4.jpg&purl=https%3A%2F%2Fimage.so.com%2F%3Fsrc%3Ddl.image&key=d7c8a3d64d', 
 'qhimg_url': 'https://p0.ssl.qhimgs1.com/t0123e59e97f75e03c4.jpg', 
 'qhimg_thumb': 'https://p0.ssl.qhimgs1.com/sdr/200_200_/t0123e59e97f75e03c4.jpg', 'qhimg_qr_key': 
 'a6e2994700', 
 'tag': '0', 
 'rdate': 
 '1502943765', 
 'ins_time': '2017-08-17 12:22:45', 
 'dsptime': '',
  'summary': [], 
  'pic_desc': ' 宝马旅行版概念车'}]}
>>>

  如上所示,响应结果(json)中的list字段是一个图片信息列表,count字段是列表中图片信息的数量,每一项图片信息的qhimg_url字段是图片下载地址。
  连续滚动鼠标滚轮加载图片,捕获更多jQuery发送的请求:
第1次加载:https://image.so.com/zjl?ch=car&listtype=new&sn=30
第2次加载:https://image.so.com/zjl?ch=car&listtype=new&sn=60
第3次加载:https://image.so.com/zjl?ch=car&listtype=new&sn=90
……
  经过观察,可以总结出这些url的规律:
● ch参数 分类标签。
● sn参数 从第几张图片开始加载,即结果列表中第一张图片在服务器端的序号。
  我们可以通过这个API每次获取固定数量的图片信息,从中提取每一张图片的url(下载地址),直到响应结果中的count字段为0(意味着没有更多图片了)。
  到此,页面分析工作完成了。

9.3.3 编码实现

  接下来,我们按以下3步完成该项目:
(1)创建Scrapy项目,并使用scrapy genspider命令创建Spider。
(2)在配置文件中启用ImagesPipeline,并指定图片下载目录。
(3)实现ImagesSpider。
  步骤 01 首先创建Scrapy项目,取名为so_image,再使用scrapygenspider命令创建Spider。

$ scrapy startproject so_image
$ cd so_image
$ scrapy genspider images image.so.com

  步骤 02 在配置文件settings.py中启用ImagesPipeline,并指定图片下载目录,代码如下:

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

步骤 03 实现IamgesSpider,代码如下:

import scrapy
import json
from scrapy import Request
from ..items import SoImageItem
class ImagesSpider(scrapy.Spider):
    BASE_URL = 'https://image.so.com/zjl?ch=car&listtype=new&sn=%s'
    start_index = 0

    # 限制最大下载数量,防止磁盘用量过大
    MAX_DOWNLOAD_NUM = 200

    name = 'images'
    # allowed_domains = ['image.so.com']
    start_urls = [BASE_URL % 0]  # 'http://image.so.com/'

    def parse(self, response):
        #item = SoImageItem()
        # 使用json 模块解析响应结果
        infos = json.loads(response.body.decode('utf-8'))
        # 提取所有图片下载url 到一个列表, 赋给item的'image_urls'字段
        yield {'image_urls': [info['qhimg_url'] for info in infos['list']]}
        #yield item
        # 如count 字段大于0,并且下载数量不足MAX_DOWNLOAD_NUM,继续获取下图片信息
        self.start_index += infos['count']
        if infos['count'] > 0 and self.start_index < self.MAX_DOWNLOAD_NUM:
            yield Request(self.BASE_URL % self.start_index)
        # pass

  编码完成后,运行爬虫:

$ scrapy crawl images

  运行结束后,查看图片下载目录download_images,如图9.3.3-1所示,我们成功爬取到了210张汽车图片。
图9.3.3-1

图9.3.3-1
  到此,图片下载的项目完成了。

9.4 本章小结

  本章我们学习了在Scrapy中下载文件和图片的方法,先简单介绍了Scrapy提供的FilesPipeline和ImagesPipeline,然后通过两个实战项目演示了FilesPipeline和ImagesPipeline的使用。

延申:

注意:

1.下载需要模块需齐全

  在下载图片之前,必须保证下载所需模块pillow

pip install pillow

  否则,会出现运行无错误,但无下载文件的情况。

2.调试文件

  如果需要调试文件,可以在scrapy.cfg同级目录,自己建立一个main,py ,设置断点进行调试,main,py 内容如下所示:

from scrapy.cmdline import execute
import os
import sys

if __name__ == '__main__':
    sys.path.append(os.path.dirname(os.path.abspath(__file__)))
    execute(['scrapy', 'crawl', 'images'])

3.改目录及名字

  由于生成文件目录和文件名类似于filespipeline中对request.url 进行sha加密的方法,因此名字不太清楚,如果需要自己要修改名字还需要进行进一步的处理。
1.新建Item field ,在item.py 新建url 和title Field()
注图1
2.修改spider中的数据保存方式
注图2注图33. 自己建立pipeline继承imagepipeline类,来处理item数据以及变换保存路径
注图4

其中,在保存图片名字时候传输的title 可能有重复的情况,为了区分,在保存图片时候,加入了时间和随机数的组合来保存不同图片。
4.更改setting.py 中的item_pipelines 的内容,为自己建立的pipeline子类,并设置图片保存路径。
由于不需要浏览器其他的设置就能下载之后就可以运行了
注图5
找到对应路径 ,运行以下代码,,如果都正确的话,即可得到结果:

# scrapy crawl images

打开对应文件目录可以得到下载的图片,大概一千张图片:
注图6
    本文开头参照《精通Scrapy网络爬虫+(刘硕著)》PDF,并自己跑相关代码,后来根据自己的想法将代码内容稍作修改以作尝试,仅做参考和笔记复习使用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值