Python爬蟲 - scrapy - 爬取妹子圖 Lv1

0. 前言

這是一個利用python scrapy框架爬取網站圖片的實例,本人也是在學習當中,在這作個記錄,也但願能幫到須要的人。爬取妹子圖的實例打算分紅三部分來寫,嘗試完善實用性。html

系統環境

System Version:Ubuntu 16.04
Python Version:3.5.2
Scrapy Version:1.5.0前端

1. 創建Scrapy項目(略)

可參考《Python爬蟲 - scrapy - 爬取豆瓣電影TOP250》python

我創建的項目名稱爲:spider_meizituweb

2. items文件

<項目目錄>/spider_meizitu/items.py
import scrapy

class SpiderMeizituItem(scrapy.Item):
    images = scrapy.Field()
    image_urls = scrapy.Field()
注意:這裏的 SpiderMeizituItem名字是能夠改的,可是 imagesimage_urls兩個變量名稱暫時不要改,緣由後面說。

3. 爬蟲文件

3.1 完整文件

<項目目錄>/spider_meizitu/spiders/meizitu.py
from scrapy import Request
from scrapy.spiders import Spider
from spider_meizitu.items import SpiderMeizituItem

class MeizituSpider(Spider):
    #爬蟲名稱
    name = 'meizitu'
    
    #開始的url
    start_urls = {
        'http://www.meizitu.com/a/sexy.html'
    }
    
    #處理函數
    def parse(self, response):
        meizi_titles = response.xpath('//ul[@class="wp-list clearfix"]/li')
        for meizi_title in meizi_titles:
            meizi_url = meizi_title.xpath('.//h3[@class="tit"]/a/@href').extract()[0]
            yield Request(meizi_url,callback=self.parse_meizi_pic)

    #處理函數跳轉
    def parse_meizi_pic(self,response):
        item = SpiderMeizituItem()
        meizitu_pics = response.xpath('//div[@id="picture"]/p/img')

        for meizitu_pic in meizitu_pics:
            item['images'] = meizitu_pic.xpath('.//@alt').extract()[0].split(',')[0]
            item['image_urls'] = meizitu_pic.xpath('.//@src').extract()
            yield item

3.2 詳細說明

name和start_urls就不說了,略過。segmentfault

parse函數

首先看一下妹子圖網站的結構,打開咱們的start_urls
前端頁面:api

clipboard.png

再看源碼:服務器

clipboard.png

能夠看到,全部的圖片項目是在一個<ul>標籤下的<li>標籤。而每一個圖片的連接打開後會進入一個新的頁面,那裏纔是咱們要下載的圖片。因此,第一步,要解析這些頁面連接,下面這段代碼創建了一個<li>標籤的集合。框架

meizi_titles = response.xpath('//ul[@class="wp-list clearfix"]/li')

meizi_titles中的每個子項都是一個<li>標籤。接下來在meizi_titles集合中作迭代循環,繼續解析<li>標籤中的內容。dom

for meizi_title in meizi_titles:

看下<li>標籤中的源碼:scrapy

clipboard.png

注意,第一個img鏈接中的limg.jpg只是縮略圖,並非咱們想要的內容。<h3>標籤中的鏈接纔是後面的頁面,咱們要把這個連接解析出來。

meizi_url = meizi_title.xpath('.//h3[@class="tit"]/a/@href').extract()[0]

解析完成後,咱們要爬蟲請求新的頁面,那裏纔有咱們須要的圖片:

yield Request(meizi_url,callback=self.parse_meizi_pic)

這裏的callback參數將頁面請求結果發送給了當前class下面的parse_meizi_pic函數。解析過程與前面的頁面大同小異,不細說了。

惟一須要說明的是item['image_urls']中存儲的變量必須是list類型的,若是不是,後期在pipeline處理時會報錯,沒法解析url。(這個說明的前提是不自定義 ImagesPipeline

當爬蟲完成item的模型數據採集後,scrapy會自動將item發送給Pipeline處理。

4. settings.py

<項目目錄>/spider_meizitu/settings.py

須要修改的項目

ITEM_PIPELINES = {
    'scrapy.contrib.pipeline.images.ImagesPipeline': 1,
}

#圖片存儲路徑,根據本身的狀況修改
IMAGES_STORE = '/home/sftp_root/spider_meizitu/meizitu'

#一些USER_AGENT
USER_AGENT_LIST = [
    'zspider/0.9-dev http://feedback.redkolibri.com/',
    'Xaldon_WebSpider/2.0.b1',
    'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0) AddSugarSpiderBot www.idealobserver.com',
    "Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.0.04506.30)",
    'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) Speedy Spider (http://www.entireweb.com/about/search_tech/speedy_spider/)',
    'Mozilla/5.0 (compatible; Speedy Spider; http://www.entireweb.com/about/search_tech/speedy_spider/)',
    "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0)",
    "Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 1.0.3705; .NET CLR 1.1.4322)",
    "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/523.15 (KHTML, like Gecko, Safari/419.3) Arora/0.3 (Change: 287 c9dfb30)",
    "Mozilla/5.0 (X11; U; Linux; en-US) AppleWebKit/527+ (KHTML, like Gecko, Safari/419.3) Arora/0.6",
    "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.2pre) Gecko/20070215 K-Ninja/2.1.1",
    "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9) Gecko/20080705 Firefox/3.0 Kapiko/3.0",
    "Mozilla/5.0 (X11; Linux i686; U;) Gecko/20070322 Kazehakase/0.4.5",
    'Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/60.0.3112.113 Chrome/60.0.3112.113 Safari/537.36',
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36',
    'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.104 Safari/537.36 Core/1.53.2372.400 QQBrowser/9.5.11096.400',
    'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:55.0) Gecko/20100101 Firefox/55.0'
    'Nusearch Spider (www.nusearch.com)',
    'nuSearch Spider (compatible; MSIE 4.01; Windows NT)',
    'lmspider (lmspider@scansoft.com)',
    'lmspider lmspider@scansoft.com',
    'hl_ftien_spider_v1.1',
    'hl_ftien_spider',
    'everyfeed-spider/2.0 (http://www.everyfeed.com)',
    'envolk[ITS]spider/1.6 (+http://www.envolk.com/envolkspider.html)',
    'envolk[ITS]spider/1.6 ( http://www.envolk.com/envolkspider.html)',
    'Baiduspider+(+http://www.baidu.com/search/spider_jp.html)',
    'Baiduspider+(+http://www.baidu.com/search/spider.htm)',
    'BaiDuSpider',    
    ]

#隨機發送UserAgent
DOWNLOADER_MIDDLEWARES = {
    'spider_meizitu.middlewares.RandomUserAgentMiddleware': 400,

}

#每次下載圖片的延遲時間
DOWNLOAD_DELAY = 3

特別須要說明的是ITEM_PIPELINES參數。若是你看過其餘的下載圖片的爬蟲文章,應該注意到我沒有寫本身的Pipeline。若是將ITEM_PIPELINES內容指定爲scrapy.contrib.pipeline.images.ImagesPipeline,那麼在spider完成item採集後,Scrapy會自動開啓系統默認的ImagesPipeline處理通道,這也是以前定義item的時候,imagesimage_urls兩個參數名稱不能更改的緣由。具體內容可參考官方文檔下載項目圖片章節

5. middlewares.py

<項目目錄>/spider_meizitu/middlewares.py
from spider_meizitu.settings import USER_AGENT_LIST
import random

class RandomUserAgentMiddleware():
    def process_request(self, request, spider):
        ua  = random.choice(USER_AGENT_LIST)
        if ua:
            request.headers.setdefault('User-Agent', ua)

在這個實例中,middlewares的惟一功能就是想web服務器發送隨機的USER_AGENT

6. 執行結果

clipboard.png

後續計劃

Lv2 爬取多頁面的妹子圖

Lv3 嘗試更改圖片文件名,並分目錄存儲

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息