scrapy時尚網站onylady圖片分類爬蟲

*本文在Windows+pycharm(Python3.5)+scrapy環境下完成爬蟲工作。

一. scrapy原理及本文爬取思路簡介:

1.scrapy經典原理圖講解:

  • Scrapy是一個用 Python 寫的 Crawler Framework,是基於Twisted的異步處理框架,是純python實現的快速,高層次的屏幕抓取和web抓取框架,用戶只需要定製開發幾個模塊就可以輕鬆的實現一個爬蟲,用來抓取網頁內容或者各種圖片。Scrapy提供了一個item pipeline ,來下載屬於某個特定項目的圖片 。這條管道被稱作圖片管道,在ImagesPipeline
    類中實現,可避免重新下載最近已經下載過的圖片。下圖顯示了Scrapy的大體架構:

這裏寫圖片描述
注意到圖片中心是引擎控制着整個爬取工作的運行。Scrapy運行流程如下:

  • 引擎打開一個網站(open a domain),找到處理該網站的Spider並向該 spider請求第一個要爬取的URL(s)。
    -引擎從Spider中獲取到第一個要爬取的URL並在調度器(Scheduler)以Request調度。
  • 引擎向調度器請求下一個要爬取的URL。
  • 調度器返回下一個要爬取的URL給引擎,引擎將URL通過下載中間件(請求(request)方向)轉發給下載器(Downloader)。
  • 一旦頁面下載完畢,下載器生成一個該頁面的Response,並將其通過下載中間件(返回(response)方向)發送給引擎。
  • 引擎從下載器中接收到Response並通過Spider中間件(輸入方向)發送給Spider處理。
  • Spider處理Response並返回爬取到的Item及(跟進的)新的Request給引擎。
  • 引擎將(Spider返回的)爬取到的Item給Item Pipeline,將(Spider返回的)Request給調度器。
  • (從第二步)重複直到調度器中沒有更多的request,引擎關閉該網站。

2.本文爬取思路簡介:

  • 進入到onlylady網站圖片網http://pic.onlylady.com/cate-10004_50_3.shtml我們要爬取服飾、街拍、達人、潮品搭配這四類並分類存儲圖片
  • 首先設定start_url(這裏很方便直接設置了四個,50是最後一頁,相當於程序設置倒着爬,這樣便於四類統一)
  • 我們爬完一頁時候需要找到類別title,圖片url(找到的是小圖,程序中要設置調整圖片大小),然後還要找到下一次要爬取的頁的url鏈接。我這裏是用火狐瀏覽器的原審查元素功能+firebug審查元素功能查看xpath表達式的。接着進入爬蟲。

二.爬取流程及代碼

1.爬取流程

-創建爬蟲工程:cmd命令下進入你的某目錄:
scrapy startproject jiandan
-創建爬蟲文件jd
cd jiandan
scrapy genspider -t basic jd onlylady.com
看下生成的項目結構:

-開始編寫程序啦:
設定初始start_url
編寫spiders:主要完成新的url列表解析和圖片鏈接解析。
編寫圖片管道:實現圖片自動下載,縮略圖下載,遇到錯誤非圖片鏈接會自動拋棄,不重複下載的任務。(設置存儲目錄)
Setting:設置打開圖片管道,設置存儲位置,縮略圖尺寸,ROBOTSTXT_OBEY = False等。
(下面附程序及下載結果,下載速度挺快的)

2.代碼

  • items.py文件
import scrapy 
class JiandanItem(scrapy.Item):
    title = scrapy.Field()#類別,用來生成存儲目錄
    image_urls = scrapy.Field()  # 圖片的鏈接
    images = scrapy.Field()#自動生成的存儲圖片url,圖片hash和checksum
  • spiders的jd.py文件
# -*- coding: utf-8 -*-
import scrapy
from jiandan.items import JiandanItem
from scrapy.selector import Selector
from scrapy.linkextractors import LinkExtractor
from scrapy.http import HtmlResponse,Request
import logging#寫不寫都行,用來把log寫入文件file_name

class jiandanSpider(scrapy.Spider):
    name = 'onlylady'#名字可調
    allowed_domains = ['onlylady.com']
    start_urls = ["http://pic.onlylady.com/cate-10004_50_3.shtml","http://pic.onlylady.com/cate-10009_50_3.shtml","http://pic.onlylady.com/cate-10011_50_3.shtml","http://pic.onlylady.com/cate-10060_50_3.shtml"]#初始的url,scrapy很方便強大吧
    def parse(self, response):
        imageurl=[]
        item = JiandanItem()
        item['title']=''.join(response.xpath('//head/title/text()').extract()[0])#根據xpath獲取title,此處 ''.join()是爲了在後面爲圖片自定義名稱時使用,若不加''.join(),後面調用item['title']會得到Unicode碼

        imageurl = response.xpath('//img/@src').extract()  # 提取圖片鏈接
        item['image_urls']=[i.replace('375x375','985x695') for i in imageurl]#小圖轉大圖鏈接
        # print 'image_urls',item['image_urls']
        yield item
        n_url = response.xpath('//a[@class="n"]//@href').extract_first()  # 翻頁
        new_url = "http://pic.onlylady.com/" + str(n_url)#構造出下頁的url
    # print 'new_url',new_url
        if new_url:
            yield scrapy.Request(new_url, callback=self.parse)#根據scrapy爬蟲流程,回調函數用來把new_url傳到調度器生成request
           # self.log("your log information")
  • pipelines.py
import os
import urllib
import scrapy
import json
import codecs
from scrapy.exceptions import DropItem
from scrapy.contrib.pipeline.images import ImagesPipeline
from scrapy.pipelines.images import ImagesPipeline
from jiandan import settings

class JiandanPipeline(object):#用來自定義圖片存儲
    def __init__(self):
        self.file = codecs.open('jiandan.json', 'w', encoding='utf-8')#title是中文,需轉碼#當運行scrapy crawl onlylady -o items.json後,數據默認保存爲items.json,裏面中文全爲Unicode,重新打開或創建一個文件'jiandan.json',名稱隨意
    def process_item(self, item, spider):
        line = json.dumps(dict(item), ensure_ascii=False) + "\n"
        self.file.write(line)
        return item
    def spider_closed(self, spider):
        self.file.close()

class JiandanPipeline(ImagesPipeline):  # 繼承ImagesPipeline這個類,實現這個功能
    def get_media_requests(self, item, info):  # 重寫ImagesPipeline   get_media_requests方法
        for image_url in item['image_urls']:
            yield scrapy.Request(image_url,meta={'item':item})
    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

    def file_path(self, request, response=None, info=None):#自定義存儲路徑
        item = request.meta['item']  # 通過上面的meta傳遞過來item
        image_guid = request.url.split('/')[-1]
        filename = u'full/{0}/{1}'.format(item['title'], image_guid)#title爲二級目錄
        return filename
  • settings.py
BOT_NAME = 'jiandan'
SPIDER_MODULES = ['jiandan.spiders']
NEWSPIDER_MODULE = 'jiandan.spiders'
ROBOTSTXT_OBEY = False
LOG_FILE  ="file_name"#日誌文件
ITEM_PIPELINES = {'jiandan.pipelines.JiandanPipeline': 300,
  'jiandan.pipelines.ImagesPipeline':1,
}#開啓兩個管道
#ITEM_PIPELINES = {'scrapy.contrib.pipeline.images.ImagesPipeline': 1}
IMAGES_STORE='f:\\onlylady'#設置自己的存儲路徑

#我在這裏關閉縮略圖功能了
'''IMAGES_THUMBS = {#縮略圖的尺寸,設置這個值就會產生縮略圖

    'small': (50, 50),

    'big': (200, 200),

}'''

-大功告成,cmd命令下 scrapy crawl onlylady
-爬取結果部分: 這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章