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

  • 我的博客原文地址:

scrapy時尚網站onylady圖片分類爬蟲 - CSDN博客?

blog.csdn.net圖標

(博客還有一些深度學習圖像分類與分割的初學文章,該更新了。)

一. 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網站圖片網pic.onlylady.com/cate-1503.shtml

  • 首先設定start_url(這裡很方便直接設置了四個,50是最後一頁,相當於程序設置倒著爬,這樣便於四類統一)
  • 我們爬完一頁時候需要找到類別title,圖片url(找到的是小圖,程序中要設置調整圖片大小),然後還要找到下一次要爬取的頁的url鏈接。我這裡是用火狐瀏覽器的原審查元素功能+firebug審查元素功能查看xpath表達式的。接著進入爬蟲。

二.爬取流程及代碼

1.爬取流程

-創建爬蟲工程:cmd命令下進入你的某目錄:

scrapy startproject jiandan-創建爬蟲文件jdcd jiandanscrapy genspider -t basic jd onlylady.com

看下生成的項目結構:

-開始編寫程序啦:

設定初始starturl編寫spiders:主要完成新的url列表解析和圖片鏈接解析。

編寫圖片管道:實現圖片自動下載,縮略圖下載,遇到錯誤非圖片鏈接會自動拋棄,不重複下載的任務。(設置存儲目錄)

Setting:設置打開圖片管道,設置存儲位置,縮略圖尺寸,ROBOTSTXTOBEY = 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 scrapyfrom jiandan.items import JiandanItemfrom scrapy.selector import Selectorfrom scrapy.linkextractors import LinkExtractorfrom scrapy.http import HtmlResponse,Requestimport logging#寫不寫都行,用來把log寫入文件file_nameclass 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 osimport urllibimport scrapyimport jsonimport codecsfrom scrapy.exceptions import DropItemfrom scrapy.contrib.pipeline.images import ImagesPipelinefrom scrapy.pipelines.images import ImagesPipelinefrom jiandan import settingsclass 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) + "
" 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 = ufull/{0}/{1}.format(item[title], image_guid)#title為二級目錄 return filename

  • settings.py

BOT_NAME = jiandanSPIDER_MODULES = [jiandan.spiders]NEWSPIDER_MODULE = jiandan.spidersROBOTSTXT_OBEY = FalseLOG_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

-爬取結果部分:


推薦閱讀:
相关文章