Scrapy爬圖片(一)

Scrapy第二篇: 多層次網頁爬取 | 圖片爬取

看到這個標題,目測一大波老司機心裡開始os:難道又是 妹子圖???

(我。。。我還能說什麼)

寶寶的品位可不一般的好吧!!!

這年代最流行什麼呀?

當然是「女神」,「校花」啦!!!(額,說「網紅」的當我沒說。。)

顏值高,有范兒,關鍵氣質逆天對不對~

比如這樣:

這樣:

或者這樣:

這樣:

不錯吧?

(嘿嘿據說最後這個還是我川的妹子~)

心動不如行動,今天我們就用Scrapy把諸位女神收入囊中!

目標網站:唯一圖庫

搜索關鍵詞:校花

一、步驟

1、首先分析網站

打開上面這個頁面,下拉就是各位MM的簡介

拉至最底部就是這樣

發現規律了吧~

第2頁是這樣,點完之後發現,真的只有6頁

查看源代碼:

隨便點擊進入某個主頁

看完第一個圖,來看後面的圖

看出來了么,皆是 url=xxx+_n.html(n為1,2,3...)的結構,只要獲得前面那一串和最大頁數就可以構造了。

但是進一步分析就會發現,每個MM個人頁面內圖片的URL結構是不一樣的(這裡也要注意),如下所示:

基本上無規律可循,不能構造出來,只能從源碼中獲取圖片真實鏈接

2、思路

用Scrapy爬取思路:

1)先獲取首頁siteURL,以及標題

2)然後由其進入MM個人頁面獲取最大頁數Num和第一個圖片URL

3)構造每一個圖片地址pageURL

4)requests獲取源碼中具體原圖地址detailURL

5)獲取圖片並保存入文件,以1)中標題作為文件名

這裡就涉及到了多層次頁面爬取的問題

怎麼辦呢,不要忘了,可以用meta傳數據

二、代碼

首先來看整個項目的文件結構

因為本項目沒有用到middlewares中間件,所以刪去了

entrypoint是一個設置文件,使得程序可以在IDE中運行

只需要調用entrypoint即可運行程序

from scrapy.cmdline import executeexecute([scrapy, crawl, XiaoHua])

來看具體分塊代碼實現:

1、items部分

# -*- coding: utf-8 -*-# Define here the models for your scraped items# See documentation in:# http://doc.scrapy.org/en/latest/topics/items.htmlimport scrapyclass XiaohuaItem(scrapy.Item): # define the fields for your item here like: # name = scrapy.Field() siteURL=scrapy.Field() #首頁中各MM的URL pageURL=scrapy.Field() #每一張圖片入口URL detailURL=scrapy.Field() #圖片原圖地址 title=scrapy.Field() #MM標題 fileName=scrapy.Field() #文件夾名,每一個MM一個文件夾 path=scrapy.Field() #圖片存儲路徑(絕對路徑)

2、settings部分

# -*- coding: utf-8 -*-# Scrapy settings for XiaoHua projectBOT_NAME = XiaoHuaSPIDER_MODULES = [XiaoHua.spiders]NEWSPIDER_MODULE = XiaoHua.spiders#是否遵循機器人規則ROBOTSTXT_OBEY = False#默認是16,一次可以請求的最大次數CONCURRENT_REQUESTS=16#下載延遲DOWNLOAD_DELAY=1#Cookies設置COOKIES_ENABLED = False#headers設置DEFAULT_REQUEST_HEADERS = {Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8,Accept-Encoding:gzip, deflate, sdch,Accept-Language:zh-CN,zh;q=0.8,Cache-Control:max-age=0,Connection:keep-alive,User-Agent:Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36}#管道設置ITEM_PIPELINES = {XiaoHua.pipelines.XiaohuaPipeline: 300}

3、spiders部分

# --coding:utf-8--import scrapyfrom XiaoHua.items import XiaohuaItemfrom scrapy.http import Requestimport requestsimport reimport osimport sysreload(sys)sys.setdefaultencoding(utf-8)class Myspider(scrapy.Spider): name=XiaoHua allowed_domains=[mmonly.cc] base=rF:/Desktop/code/info/XiaoHua/ def start_requests(self): #一共有6頁 for i in range(1,7): url=https://www.mmonly.cc/tag/xh1/+str(i)+.html yield Request(url,callback=self.parse_one) def parse_one(self,response): #創建一個大的list存儲所有的item items=[] pattern=re.compile(r<div class="title".*?<a.*?href="(.*?)">(.*?)</a></span></div>,re.S) mains=re.findall(pattern,response.text) for main in mains: #創建實例,並轉化為字典 item=XiaohuaItem() item[siteURL]=main[0] item[title]=main[1] item[fileName]=self.base+item[title] items.append(item) for item in items: #創建文件夾 fileName=item[fileName] if not os.path.exists(fileName): os.makedirs(fileName) #用meta傳入下一層 yield Request(url=item[siteURL],meta={item1:item},callback=self.parse_two) def parse_two(self,response): #傳入上面的item1 item2=response.meta[item1] source=requests.get(response.url) html=source.text.encode(utf-8) #用正則提取頁數 pattern=re.compile(r共(.*?)頁,re.S) Num=re.search(pattern,html).group(1) items=[] for i in range(1,int(Num)+1): #注意這裡,創建實例的位置 item=XiaohuaItem() item[fileName]=item2[fileName] #構造每一個圖片的存儲路徑 item[path]=item[fileName]+/+str(i)+.jpg #構造每一個圖片入口鏈接,以獲取源碼中的原圖鏈接 item[pageURL]=response.url[:-5]+_+str(i)+.html items.append(item) for item in items: yield Request(url=item[pageURL],meta={item2:item},callback=self.parse_three) def parse_three(self,response): item=XiaohuaItem() #傳入上面的item2 item3=response.meta[item2] #匹配正則獲取圖片真實地址detailURL pattern=re.compile(r<li class="pic-down h-pic-down"><a target="_blank" class="down-btn" href=(.*?)>.*?</a>,re.S) URL=re.search(pattern,response.text).group(1) item[detailURL]=URL item[path]=item3[path] item[fileName]=item3[fileName] yield item

4、pipelines部分

# -*- coding: utf-8 -*-import requestsimport sysreload(sys)sys.setdefaultencoding(utf-8)#用requests的get方法獲取圖片並保存入文件class XiaohuaPipeline(object): def process_item(self, item, spider): detailURL=item[detailURL] path=item[path] fileName=item[fileName] image=requests.get(detailURL) f=open(path,wb) f.write(image.content) f.close() print u正在保存圖片:,detailURL print u圖片路徑:,path print u文件:,fileName return item

寫完代碼,直接調用entrypoint即可在IDE中運行(我用的Pycharm)

這個小項目我也放到github上了:爬取唯一圖庫美女校花

(如果您覺得有幫助,可以star我喲~)

三、結果

最後結果就是這樣的:

一共抓取2114張圖

文件是這樣

隨便打開是這樣

四、總結

最後,總結本篇關鍵:

1、Scrapy爬取多級網頁結構(主要用meta傳遞數據)

2、Scrapy爬取圖片的一般方法(別的方法放下次討論)

本篇就是這樣啦~

推薦閱讀:

未來的旅遊的熱點是什麼?旅遊點評數據分析
從零開始寫Python爬蟲 --- 2.6 爬蟲實踐:重構排行榜小說爬蟲&Mysql資料庫
從零開始寫Python爬蟲 --- 爬蟲實踐:螺紋鋼數據&Cookies
開啟知乎收藏夾看圖模式
Python模擬登陸萬能法-微博|知乎

TAG:Python | 爬虫 | scrapy |