Scrapy Shell 和 Request、Response對象

Scrapy Shell

Scrapy提供了一個shell,用來方便的測試規則。當然也不僅僅侷限於這一個功能。

打開Scrapy Shell

開cmd終端,進入到Scrapy項目所在的目錄,然後進入到scrapy框架所在的虛擬環境中,輸入命令scrapy shell [鏈接]。就會進入到scrapy的shell環境中。在這個環境中,你可以跟在爬蟲的parse方法中一樣使用了。
在這裏插入圖片描述

Request對象

在這裏插入圖片描述Request對象在我們寫爬蟲,爬取一頁的數據需要重新發送一個請求的時候調用。這個類需要傳遞一些參數,其中比較常用的參數有:

  1. url:這個request對象發送請求的url。
  2. callback:在下載器下載完相應的數據後執行的回調函數。
  3. method:請求的方法。默認爲GET方法,可以設置爲其他方法。
  4. headers:請求頭,對於一些固定的設置,放在settings.py中指定就可以了。對於那些非固定的,可以在發送請求的時候指定。
  5. meta:比較常用。用於在不同的請求之間傳遞數據用的。
  6. encoding:編碼。默認的爲utf-8,使用默認的就可以了。
  7. dont_filter:表示不由調度器過濾。在執行多次重複的請求的時候用得比較多。
  8. errback:在發生錯誤的時候執行的函數。

Response對象

Response對象一般是由Scrapy給你自動構建的。因此開發者不需要關心如何創建Response對象,而是如何使用他。Response對象有很多屬性,可以用來提取數據的。主要有以下屬性:

  1. meta:從其他請求傳過來的meta屬性,可以用來保持多個請求之間的數據連接。
  2. encoding:返回當前字符串編碼和解碼的格式。
  3. text:將返回來的數據作爲unicode字符串返回。
  4. body:將返回來的數據作爲bytes字符串返回。
  5. xpath:xapth選擇器。
  6. css:css選擇器。

發送POST請求:

在請求數據的時候發送post請求:

  1. 如果想在爬蟲一開始的時候就發送post請求,那麼應該重寫start_requests方法。在這個方法中,發送post請求。
  2. 或者在parse中使用scrapy.FormRequest.from_response()來發送請求。這是先執行了原來的start_request方法,即先GET請求start_urls中的鏈接,返回來的響應在POST請求。
# -*- coding: utf-8 -*-
import scrapy

class RenrenspiderSpider(scrapy.Spider):
    name = 'renrenspider'
    allowed_domains = ['renren.com']
    start_urls = ['http://renren.com/']

    # def start_requests(self):
    #     url = "http://www.renren.com/PLogin.do"
    #     data = {"email":"","password":""}
    #     request = scrapy.FormRequest(url,formdata=data,callback=self.parse_page)
    #     yield request
    #
    # def parse_page(self,response):
    #     print("登陸")
    #     request = scrapy.Request(url='http://www.renren.com/880151247/profile',callback=self.parse_profile)
    #     yield request
    #
    # def parse_profile(self,response):
    #     with open('dp.html','w',encoding='utf-8') as fp:
    #         fp.write(response.text)

    def parse(self, response):
        data = {"email":"","password":""}
        yield scrapy.FormRequest.from_response(response,formdata=data,callback=self.parse_page)

    def parse_page(self,response):
        print("登陸")
        request = scrapy.Request(url='http://www.renren.com/880151247/profile',callback=self.parse_profile)
        yield request

    def parse_profile(self,response):
        with open('dp.html','w',encoding='utf-8') as fp:
            fp.write(response.text)
    

下載文件和圖片

Scrapy爲下載item中包含的文件(比如在爬取到產品時,同時也想保存對應的圖片)提供了一個可重用的item pipelines。這些pipeline有些共同的方法和結構(我們稱之爲media pipeline)。一般來說你會使用Files Pipeline或者Images Pipeline。

使用內置的下載文件的方法優點:

  1. 避免重新下載最近已經下載過的文件。
  2. 可以方便的指定文件存儲的路徑。
  3. 可以將下載的圖片轉換成通用的格式。比如png或jpg。
  4. 可以方便的生成縮略圖。
  5. 可以方便的檢測圖片的寬和高,確保他們滿足最小限制。
  6. 異步下載,效率非常高。
下載文件的Files Pipeline:

當使用Files Pipeline下載文件的時候,按照以下步驟來完成:

  1. 定義好一個Item,然後在這個item中定義兩個屬性,分別爲file_urls以及files。file_urls是用來存儲需要下載的文件的url鏈接,需要給一個列表。
  2. 當文件下載完成後,會把文件下載的相關信息存儲到item的files屬性中。比如下載路徑、下載的url和文件的校驗碼等。
  3. 在配置文件settings.py中配置FILES_STORE,這個配置是用來設置文件下載下來的路徑。
  4. 啓動pipeline:在ITEM_PIPELINES中設置scrapy.pipelines.files.FilesPipeline:1。

下載圖片的Images Pipeline:

  1. 定義好一個Item,然後在這個item中定義兩個屬性,分別爲image_urls以及images。image_urls是用來存儲需要下載的圖片的url鏈接,需要給一個列表。
    items.py:
import scrapy
class CarimageItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    image_urls = scrapy.Field()
    images = scrapy.Field()
  1. 當文件下載完成後,會把文件下載的相關信息存儲到item的images屬性中。比如下載路徑、下載的url和圖片的校驗碼等。
  2. 在配置文件settings.py中配置IMAGES_STORE,這個配置是用來設置圖片下載下來的路徑。
#圖片下載路徑
IMAGES_STORE = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'images')
  1. 啓動pipeline:在ITEM_PIPELINES中設置scrapy.pipelines.images.ImagesPipeline:1
在pipeline.py中的類需要繼承ImagesPipeline或者FilesPipeline類。可以重寫ImagesPipeline和FilesPipeline中的方法來達到我們的需求

pipeline.py:

class CarimagesPipeline(ImagesPipeline):
    #綁定Items對象
    def get_media_requests(self, item, info):
        request_objs = super(CarimagesPipeline, self).get_media_requests(item,info)
        for request_obj in request_objs:
            request_obj.item = item
        return request_objs
   #重寫文件存儲路徑
    def file_path(self, request, response=None, info=None):
        path = super(CarimagesPipeline, self).file_path(request,response,info)
        cattab_title = request.item.get('cattab_title')
        category = request.item.get('category')
        images_store = os.path.join(settings.IMAGES_STORE,cattab_title)
        category_path = os.path.join(images_store,category)
        if not os.path.exists(category_path):
            os.makedirs(category_path)
        image_name = path.replace("full/","")
        image_path = os.path.join(cattab_title+'/'+category+'/',image_name)
        return image_path

注:參考網易雲知了課堂。

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