Scrapy实战篇(六)之爬取360图片数据和图片

  

  本篇文章我们以360图片为例,介绍scrapy框架的使用以及图片数据的下载。

  目标网站:http://images.so.com/z?ch=photography

  思路:分析目标网站为ajax加载方式,通过构造目标url从而请求数据,将图片数据存储在本地,将图片的属性存储在mongodb中。

  1、首先定义我们需要抓取的字段

class ImageItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    collection = ‘images‘  #代表mongodb的的集合名称
    #下面四个字段分别是图片id,链接,标题,缩率图
    id = Field()
    url = Field()
    title = Field()
    thumb = Field()

  

  2、构造我们要爬取的url;由于目标网站时ajax加载的,展示的数据在http://images.so.com/zj?ch=photography&sn=30&listtype=new&temp=1中以json的形式存储,不断的下拉页面之后,每次变化的参数只有sn,并且每次以30的增量增加,第一页sn=30,第二页为60,则sn和页码的关系为sn*30,所以我们可以构造出url

#定义起始需要爬取的url列表,首先从spider中发送给调度引擎
    def start_requests(self):
        data = {‘ch‘:‘photography‘,‘listtype‘:‘new‘,‘temp‘:1}
        base_url = ‘http://images.so.com/zj?‘
        for page in range(1,self.settings.get(‘MAX_PAGE‘) + 1):   #MAX_PAGE以参数的形式在settings文件中配置
            data[‘sn‘] = page * 30
            url = base_url + urlencode(data)
            yield Request(url,self.parse)

  3、编写解析函数,返回的数据是json格式

#解析函数
    def parse(self, response):
        result = json.loads(response.text)   #将JSON文本字符串转为JSON对象
        for image in result.get(‘list‘):
            item = ImageItem()
            item[‘id‘] = image.get(‘imageid‘)
            item[‘url‘] = image.get(‘qhimg_url‘)
            item[‘title‘] = image.get(‘group_title‘)
            item[‘thumb‘] = image.get(‘qhimg_thumb_url‘)
            yield item

  4、编写pipeline文件,将图片属性数据存入mongo,将图片存储到本地

import pymongofrom scrapy import Request
from scrapy.exceptions import DropItem
from scrapy.pipelines.images import ImagesPipeline

#定义了两个个Pipeline,分别为数据存储到mongodb,图片下载到本地
#在settings中定义Pipeline的执行顺序
class MongoPipeline(object):
    def __init__(self,mongo_url,mongo_db):
        self.mongo_url = mongo_url
        self.mongo_db = mongo_db

    @classmethod
    def from_crawler(cls,crawler):
        return cls(
            mongo_url=crawler.settings.get(‘MONGO_URL‘),
            mongo_db=crawler.settings.get(‘MONGO_DB‘)
        )

    def open_spider(self,spider):
        self.client = pymongo.MongoClient(self.mongo_url)
        self.db = self.client[self.mongo_db]

    def process_item(self, item, spider):
        self.db[item.collection].insert(dict(item))
        return item

    def close(self,spider):
        self.client.close()

class ImagesPipeline(ImagesPipeline):
    def file_path(self,request,response=None,info=None):
        url = request.url
        file_name = url.split(‘/‘)[-1]
        return file_name

    def item_completed(self,results,item,info):
        image_paths=[x[‘path‘] for ok,x in results if ok]
        if not image_paths:
            raise DropItem(‘Image Download Failed‘)
        return item

    def get_media_requests(self,item,info):
        yield Request(item[‘url‘])

第一个为MongoPipeline,通过类方法from_crawler从settings文件中获取mongodb的配置信息,将蜘蛛文件中返回的item存入mongo数据库。

第二个为ImagesPipeline,scrapy提供了专门处理下载的Pipeline,包括文件下载和图片下载,下载过程支持异步和多线程,效率极高。

首先定义存储文件的路径,需要定义一个IMAGES_STORE变量,在settings文件中添加一行

IMAGES_STORE = ‘./images

我们将路径定义在当前路径下的images中,即下载的图片都会存储在这个文件夹中。

  内置的ImagesPipeline会默认读取Item对象的image_urls字段,并认为该变量是一个列表,会遍历这个字段,然后取出url进行图片下载。

  但是我们上面定义的模型可以看出,Item对象的图片连接并不是image_url,也不是列表形式的,而是单个url,所以为了实现下载,需要重写ImagePipeline,继承内置的ImagePileline,再次我们重写了三个方法,分别是

  1)get_media_requests():它的第一个参数item就是爬取生成的Item对象,我们将它的url取出来,直接生成Request对象返回,从而加入调度队列,等待被调度,执行下载。

  2)file_path():它的第一个参数request就是当前下载的Request对象,这个方法用来返回保存的文件名称,直接将图片链接的最后一部分当做文件名称即可。

  3)item_completed():它是当单个Item完成下载时的处理方法,因为并不是每张图片都会下载成功,所以需要分析下载结果并剔除下载失败的图片,该方法的第一个参数results就是该item对象的下载结果,它是一个列表的形式,列表的每一个元素都是一个元组,其中包含了下载成功或者失败的信息。

  5、在settings中激活pipeline,并配置需要的配置项

ITEM_PIPELINES = {
   ‘images360.pipelines.ImagesPipeline‘: 300,
   ‘images360.pipelines.MongoPipeline‘: 301,
}

  6、执行爬虫,获取数据即可。

  scrapy crawl  images

原文地址:https://www.cnblogs.com/lxbmaomao/p/10372065.html

时间: 2024-10-08 03:54:50

Scrapy实战篇(六)之爬取360图片数据和图片的相关文章

Scrapy 通过登录的方式爬取豆瓣影评数据

Scrapy 通过登录的方式爬取豆瓣影评数据 爬虫 Scrapy 豆瓣 Fly 由于需要爬取影评数据在来做分析,就选择了豆瓣影评来抓取数据,工具使用的是Scrapy工具来实现.scrapy工具使用起来比较简单,主要分为以下几步: 1.创建一个项目 ==scrapy startproject Douban 得到一个项目目录如下: ├── Douban │   ├── init.py │   ├── items.py │   ├── pipelines.py │   ├── settings.py

爬虫(十七):Scrapy框架(四) 对接selenium爬取京东商品数据

1. Scrapy对接Selenium Scrapy抓取页面的方式和requests库类似,都是直接模拟HTTP请求,而Scrapy也不能抓取JavaScript动态谊染的页面.在前面的博客中抓取JavaScript渲染的页面有两种方式.一种是分析Ajax请求,找到其对应的接口抓取,Scrapy同样可以用此种方式抓取.另一种是直接用 Selenium模拟浏览器进行抓取,我们不需要关心页面后台发生的请求,也不需要分析渲染过程,只需要关心页面最终结果即可,可见即可爬.那么,如果Scrapy可以对接S

Scrapy框架学习(四)爬取360摄影美图

我们要爬取的网站为http://image.so.com/z?ch=photography,打开开发者工具,页面往下拉,观察到出现了如图所示Ajax请求, 其中list就是图片的详细信息,接着观察到每个Ajax请求的sn值会递增30,当sn为30时,返回前30张图片,当sn为60时,返回第31到60张图片,所以我们每次抓取时需要改变sn的值.接下来实现这个项目. 首先新建一个项目:scrapy startproject images360 新建一个Spider:scrapy genspider

python框架Scrapy中crawlSpider的使用——爬取内容写进MySQL

一.先在MySQL中创建test数据库,和相应的site数据表 二.创建Scrapy工程 #scrapy startproject 工程名 scrapy startproject demo4 三.进入工程目录,根据爬虫模板生成爬虫文件 #scrapy genspider -l # 查看可用模板 #scrapy genspider -t 模板名 爬虫文件名 允许的域名 scrapy genspider -t crawl test sohu.com 四.设置IP池或用户代理(middlewares.

Python爬取贴吧中的图片

#看到贴吧大佬在发图,准备盗一下 #只是爬取一个帖子中的图片 1.先新建一个scrapy项目 scrapy startproject TuBaEx 2.新建一个爬虫 scrapy genspider tubaex https://tieba.baidu.com/p/4092816277 3.先写下items #保存图片的url img_url=scrapy.Field() 4.开始写爬虫 # -*- coding: utf-8 -*-import scrapyfrom TuBaEx.items

爬取糗事百科的图片

小编,最近写了个单线程的爬虫,主要是爬取糗事百科的图片之类的,下面是源代码,小伙伴们可以拿去参照,学习 #!/usr/bin/env python# -*- coding:utf-8 -*-import requests,jsonimport requests,re,os,timeimport urllib.requestimport urllib.parseimport sslimport unittestfrom selenium import webdriver headers = {"U

Python爬取京东商品数据

对京东某一商品信息页面的HTML代码进行分析,可以发现它的图书产品信息页面都含有这样一段代码(不同类的商品页面有些不同): window.pageConfig={compatible:true,searchType: 1,product:{"skuid":"11408255","name":"\u4f17\u795e\u7684\u536b\u661f\uff1a\u4e2d\u56fd\u7981\u533a","

Python 爬取煎蛋网妹子图片

1 #!/usr/bin/env python 2 # -*- coding: utf-8 -*- 3 # @Date : 2017-08-24 10:17:28 4 # @Author : EnderZhou ([email protected]) 5 # @Link : http://www.cnblogs.com/enderzhou/ 6 # @Version : $Id$ 7 8 import requests 9 from bs4 import BeautifulSoup as bs

使用进程池模拟多进程爬取url获取数据,使用进程绑定的回调函数去处理数据

1 # 使用requests请求网页,爬取网页的内容 2 3 # 模拟使用进程池模拟多进程爬取网页获取数据,使用进程绑定的回调函数去处理数据 4 5 import requests 6 from multiprocessing import Pool 7 8 # response = requests.get('http://www.baidu.com') # 访问网页获取网页内容,得到一个网页内容的结果对象<Response [200]>这个200是一个状态码,200表示网页正常的返回,40