天天看點

爬蟲之将Scrapy爬取資料儲存至Mongodb資料庫爬蟲之将Scrapy爬取資料儲存至Mongodb資料庫

爬蟲之将Scrapy爬取資料儲存至Mongodb資料庫

需求:以1藥網中中西藥品分類中的所有頁面為目标,爬取每件商品的單價,名稱以及評論

在上一篇部落格中,我們講了Scrapy的基本使用以及各個檔案該如何配置,與上篇部落格中的案例相比,不同的地方就是在pipelines.py中對資料的處理不同。

  1. 建立爬蟲檔案
    scrapy genspider yiyaowang yiyaowang.com
               
  2. 在yiyaowang.py檔案中先編寫回調函數,先爬取一頁的資料
    # -*- coding: utf-8 -*-
    import scrapy
    
    class YaowangSpider(scrapy.Spider):
        name = 'yiyaowang'
        # allowed_domains = ['yaowang.com']
        start_urls = [https://www.111.com.cn/categories/953710]
    
        def parse(self, response):
    
            # 提取資料
            li_list = response.xpath('//ul[@id="itemSearchList"]/li')
            for li in li_list:
    			# 擷取單價
    			good_price = good.xpath('.//p[@class="price"]//span/text    ()').get().strip()
    			
    			# 擷取标題 
    			# good_title = good.xpath('.//p[@class="titleBox"]//a/te    xt()').get()
    			# 發現問題:
    			# 并沒有傳回None,而是傳回一片空白
    			# 分析:傳回空白而不是傳回None說明不是xpath路徑,可能是>    傳回的清單的第一個元素是一個空字元串
    			# 解決:先用getall()全部取出來,然後再取我們需要的資料
    			# 擷取标題
    			good_title = good.xpath('.//p[@class="titleBox"]//a/text    ()').getall()[1].strip()
    			
    			# 擷取評論
    			good_comment = good.xpath('.//a[@id="pdlink3"]//em/text(    )').get()
               
  3. 查找每一頁url的規律,循環爬取所有頁數
    第一頁:https://www.111.com.cn/categories/953710-j1.html
    第二頁:https://www.111.com.cn/categories/953710-j2.html
    ...
    最後一頁:https://www.111.com.cn/categories/953710-j50.html
               

    總結發現:頁數一共為50頁,唯一變化的為j後面的數字,并且數字與頁數對應

    在原有代碼上進行添加

    # -*- coding: utf-8 -*-
    import scrapy
    
    class YaowangSpider(scrapy.Spider):
        name = 'yiyaowang'
        # allowed_domains = ['yaowang.com']
        # -------------------------------------------------------------------------
        start_urls = []
    	base_url = "https://www.111.com.cn/categories/953710-j{}.html"
    		# 得到每一頁的url
    		for i in range(1,51):
    			start_urls.append(base_url.format(i))
    	# -------------------------------------------------------------------------
    
        def parse(self, response):
    
            # 提取資料
            li_list = response.xpath('//ul[@id="itemSearchList"]/li')
            for li in li_list:
    			# 擷取單價
    			good_price = good.xpath('.//p[@class="price"]//span/text    ()').get().strip()
    			
    			# 擷取标題
    			good_title = good.xpath('.//p[@class="titleBox"]//a/text    ()').getall()[1].strip()
    			
    			# 擷取評論
    			good_comment = good.xpath('.//a[@id="pdlink3"]//em/text(    )').get()
               
  4. 至此資料已經爬取資料,接下來要先進行資料的處理
    在items.py中編寫相應的類
    class YiYaoWang(scrapy.Item):
        # 定義标題
        title = scrapy.Field()
        # 定義單價
        price = scrapy.Field()
        # 定義評價
        comment = scrapy.Field()
    
               
  5. 将資料放入item中準備讓管道調用
    import scrapy
    
    # 讀入item中的類
    # ------------------------------------------------------------
    from ..items import YiYaoWang
    # ------------------------------------------------------------
    
    class YiyaowangSpider(scrapy.Spider):
        name = 'yiyaowang'
        # allowed_domains = ['yiyaowang.com']
        start_urls = []
        base_url = "https://www.111.com.cn/categories/953710-j{}.html"
        # 得到每一頁的url
        for i in range(1,51):
            start_urls.append(base_url.format(i))
    
        def parse(self, response):
            """從連結中擷取資料"""
            good_list = response.xpath('//ul[@id="itemSearchList"]/li')
    
            # 執行個體化item對象
            # ----------------------------------------------------------
            item = YiYaoWang()
            # ----------------------------------------------------------
    
            # 擷取資料
            for good in good_list:
                # 擷取單價
                price = good.xpath('.//p[@class="price"]//span/text()').get().strip()
    
                # 擷取标題
                # good_title = good.xpath('.//p[@class="titleBox"]//a/text()').get()
                # 發現問題:
                # 并沒有傳回None,而是傳回一片空白
                # 分析:傳回空白而不是傳回None說明不是xpath路徑,可能是傳回的清單的第一個元素是一個空字元串
                # 解決:先用getall()全部取出來,然後再取我們需要的資料
                # 擷取标題
                title = good.xpath('.//p[@class="titleBox"]//a/text()').getall()[1].strip()
    
                # 擷取評論
                comment = good.xpath('.//a[@id="pdlink3"]//em/text()').get()
                
                # ---------------------------------------------------------------
                # 處理資料
                item["title"] = title
                item["price"] = price
                item["comment"] = comment
        		# ---------------------------------------------------------------
        		
                yield item
    
               
  6. 在pipelines.py管道檔案中編寫資料儲存的類
    class YiYaoWangPipeline:
        def open_spider(self,spider):
            # 建立連結
            self.client = pymongo.MongoClient(host="127.0.0.1",port=27017)
            # 進入資料庫
            self.db = self.client["first_text"]
            # 進入集合
            self.col = self.db["yiyaowang"]
    
        def process_item(self,item,spider):
            # 插入資料
            self.col.insert({"标題":item["title"],"單價":item["price"],"評論>數":item["comment"]})
            return item
    
        def close_spider(self,spider):
           self.client.close()
    
               
  7. 将寫好的管道加入到settings.py配置檔案中
    必須把以前爬蟲檔案的管道設定注釋掉,不然以前爬蟲檔案的管道也會在現在的爬蟲檔案中運作一次,儲存資料的參數不一樣時就會報錯
    # Configure item pipelines
    # See https://docs.scrapy.org/en/latest/topics/item-pipeline.html
    ITEM_PIPELINES = {
        # 'reptile.pipelines.ReptilePipeline': 300,
    	# 'reptile.pipelines.HuPuPipeline': 300,
     'reptile.pipelines.YiYaoWangPipeline': 300,
    }
               
  8. 執行爬蟲檔案
    scrapy crawl yiyaowang
               
  9. 打開指令視窗檢視是否儲存到了資料庫
    MongoDB Enterprise > show tables
    yiyaowang