用scrapy抓取网站图片

学习Python,就避免不了爬虫,而Scrapy就是最流行的一个。你可以爬取文字信息(如招聘职位信息,网站评论等),也可以爬取图片,比如看到一些好的网站展示了很多精美的图片(这里只用作个人学习Scrapy使用,不作商业用途),可以download下来。好了,不多说,现在开始一个最简单的图片爬虫。

首先,我们需要一个浏览器,方便查看html路径,这里推荐使用火狐开发者版(https://www.mozilla.org/en-US/firefox/developer/) 这个版本的火狐logo是蓝色的哦

装了这个,你不需要在去装firebug,firepath之类的插件

这里的例子,以花瓣网为例,抓取http://www.meisupic.com/topic.php 这个页面的图片。

Step 1: Open Firefox and access with above URL, navigate to Inspector tab, click arrow and then select a picture, you then can see the location of selected picture (see below)
用scrapy抓取网站图片

在这里我们发现,打开的页面包含了很多主题的图片,然后每个主题对应一个图片链接地址,打开之后,就是这个主题下面对应的图片。那我们的目的是抓取每一个主题下面的图片,所以,第一步要获取每个主题的链接,打开这个链接,在查看图片的地址,然后一个一个download。现在大概知道了我们这个例子有两层结构:①访问主页,展示的是不同主题的图片 ②打开每一个主题,展示的这个主题下面的图片

现在开始创建一个scrapy的工程(可以参考之前的文章https://blog.51cto.com/waytogo/2092238)

这里我创建了一个huaban2的project(之前有做另一个,所以这里命名为huaban2,想写什么名都可以),然后再创建一个spider,begin是一个command line的文件,里面是就scrapy crawl meipic的命令,一会再看
用scrapy抓取网站图片

Step 2: Implement a spider

# -*- coding: utf-8 -*-
from huaban2.items import Huaban2Item
import scrapy

class HuabanSpider(scrapy.Spider):
    name = 'meipic'
    allowed_domains = ['meisupic.com']
    baseURL = 'http://www.meisupic.com/topic.php'
    start_urls = [baseURL]

    def parse(self, response):
        node_list = response.xpath("//div[@class='body glide']/ul")
        if len(node_list) == 0:
            return
        for node in node_list:
            sub_node_list = node.xpath("./li/dl/a/@href").extract()
            if len(sub_node_list) == 0:
                return
            for url in sub_node_list:
                new_url = self.baseURL[:-9] + url
                yield scrapy.Request(new_url, callback=self.parse2)

    def parse2(self, response):
        node_list = response.xpath("//div[@id='searchCon2']/ul")
        if len(node_list) == 0:
            return
        item = Huaban2Item()
        item["image_url"] = node_list.xpath("./li/a/img/@data-original").extract()
        yield item

解释一下这段代码:在用 scrapy genspider meipic meisupic.com 生成spider之后,默认的结构已经写好了,这里我们设置了一个baseURL, parse是默认的方法。从上面的分析中得知,我们需要拿到每一个主题的链接,所以用xpath定位

node_list = response.xpath("//div[@class='body glide']/ul")

这样我们得到一个selector对象,赋给变量node_list,加个if判断一下,如果没了就结束(return之后的代码都不会执行,这个大家应该都知道),接着我们要取/ul/li/dl下面的a中的href,取到之后,用extract(),返回一个list,就是dl下面所有<a>中的链接,接下来,我们需要拼接一个完整的URL,然后请求这个URL,用yield返回。因为我们真正要抓取的图片在第二层页面,所以这里的回调函数(callback)调用一个parse2(这是自己定义的一个方法),parse2用来处理图片链接。同理,parse2的response就是之前拼接的URL请求的页面返回的
用scrapy抓取网站图片

这里我们要到得到图片的地址,就是//div[@id='SearchCon2‘]/ul/li/a/img/@data-original,拿到地址之后,把它给item(我们定义了item的字段,用来存储图片的地址),这样item返回给pipeline

items.py

import scrapy

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

pipelines.py

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

class Huaban2Pipeline(ImagesPipeline):

    def get_media_requests(self, item, info):
        for image_url in item['image_url']:
            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 image")
        item['image_paths'] = image_paths
        return item

因为要下载图片,所以需要在settings.py里配置一个路径,同时
需要的配置如下,其他默认就好

MEDIA_ALLOW_REDIRECTS = True #因为图片地址会被重定向,所以这个属性要为True
IMAGES_STORE = "E:\\img"  #存储图片的路径
ROBOTSTXT_OBEY = False  #Robot协议属性要为False,不然就不会抓取任何内容
ITEM_PIPELINES = {
    'huaban2.pipelines.Huaban2Pipeline': 1,
} #pipeline要enable,不然不会出来pipeline的请求

最后,我们写了一个begin.py的文件,用来执行

from scrapy import cmdline

cmdline.execute('scrapy crawl meipic'.split())

多说一点,可以存储不同图片尺寸,如果需要可以加属性在settings.py里

IMAGES_THUMBS = {'small': (100, 100), 'big': (800, 1000)}

好了,基本的都已经写好了,可以开始执行了。

转载于:https://blog.51cto.com/waytogo/2109243

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值