聽完幾首歌,開始今天的爬蟲課程,這部分主要是對管道使用的介紹,本部分講完,後面再一個綜合案例就結束了,最好今天能夠把這部分搞熟,包括案例的理解,可以結合前五篇一起回顧scrapy的特性和那張部件流程圖。
課前導入:
目錄
1.ItemPipeline的介紹
對於管道的學習,在前面通過對scrapy項目中item的講解可以知道,這個是用來傳遞數據的管道,上部分說的對數據進行去重和清洗,就是在這部分完成的,也就是說Item數據對象在spider採集器中被收集到後,傳到ItemPipeline,這部分的學習就是講傳到pipeline後的操作。下面用老師的課件進行理解:
對於pipeline的具體應用,後面的演示主要是第四個應用,前三個對於實際應用較爲重要,比如對於業務真實數據的採集,是很有必要的。
2.如何自定義ItemPipeline
講完理論知識,可以來看看怎麼構造item pipeline,在scrapy項目中已經生成了一個模板,但需要我們針對自己的實際需要再進行自定義新的類(在同一文件即可,注意命名不要重複)。
在講這部分的時候,PPT上老師的要點較爲簡略,跟着講義補充了更多細節,聽到老師說在官方網站上有更多功能的介紹,學習着參看文檔,這樣更準確,而且更能擴展其他用法。
找到文檔部分,想學習一門編程語言或者框架,善用文檔。鏈接貼在這裏,【scrapy文檔】
3.Scrapy的案例實戰
這部分的主要內容是完成csdn上的課程信息爬取,並存儲入庫。跟着老師的演示完成後,現在來回顧一下幾個主要的步驟,包括需要注意的點,僅供參考,如有遺漏,純屬不夠熟練,期待進步空間。
- 創建項目 :在指定的項目路徑下,打開命令行界面,使用【scrapy startproject csdnedu】;
- 創建爬蟲:創建項目成功後,進入項目目錄【cd csdnedu】,並使用【scrapy genspider course csdn.edu.net】命令來創建爬蟲;
- 爬蟲體的完善:此時,已經有一個爬蟲項目和具體的爬蟲文件course.py在spider文件目錄下,使用編譯器完成對爬蟲文件、Items文件、settings文件的修改,其中爬蟲文件的採集規則要針對採集頁的網頁結構特點以及採集目標的所在位置,有選擇性的使用selector、css或re匹配到目標,並使用導入的items中定義好的新item對象,將目標對應值傳遞給item,最後使用page的特點進行增改,構建新的url並自調爬蟲文件中的parse函數完成多頁爬取設置;
- 編寫存入MySQL:確定可以爬取到採集目標後,確定當前編譯環境下裝好了pymysql包,導入包對管道文件,也就是pipelines文件進行修改,修改可以新增類MySQLPipeline,其中對open_spider和close_spider兩個函數重寫,重寫內容中open函數中對於sql語句的使用和遊標的獲取不要忘了,還有函數參數的傳遞,這個部分側重可以看下方代碼,按我理解的寫主要步驟,其中爲了將數據庫的連接信息可重用,將其寫入settings文件 ,並用依賴注入裝飾器的方法,將其自調用並實例化傳遞給spider。這個部分有兩個地方容易犯錯,第一個是傳遞過程中SQL語句中“%s”所對應的數據庫中屬性,不要大寫%S,不要寫%d,第二個是3306是端口號,不是字符串,切記不要使用“ ”引號傳遞,直接賦值即可,另外,確定數據庫名稱及表名和屬性值都是提前創建好的,這部分是採集新增操作,需要先創建好再運行項目;
- 調試設置:經過一遍檢查,代碼確實無誤,在settings文件中繼續修改,將ItemPipeline及後面的{ }花括號內容取消註釋,添加一行新增類的說明,即第4步驟中對於MysqlPipeline,同上行300的一樣就行,只是修改300爲301。
- 運行檢查:差不多就完成了。運行並且查看結果,進行調試。成功看數據庫結果,不成功的話看報錯的地方,修復。重複以上直到數據庫表中出現爬取結果數據。
上方是對於步驟的回憶體,一不小心寫多了,過於具體,代碼過程中有寫註釋,可以參看代碼理解。以下:
items文件對於目標信息類的設計:
# -*- coding: utf-8 -*-
# items.py文件
# Define here the models for your scraped items
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/items.html
import scrapy
class EducsdnItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
# 課程信息item類:課程標題、URL地址、圖片、講師、時長、價格
title = scrapy.Field()
url = scrapy.Field()
pic = scrapy.Field()
teacher = scrapy.Field()
time = scrapy.Field()
price = scrapy.Field()
pass
course文件是爬蟲體,關鍵的部分,其中對於目標網頁的解析和頁數控制、封裝信息傳遞,都需要放在這個部分,是genspider命令後自動生成的。
# -*- coding: utf-8 -*-
# courses.py文件
import scrapy
import educsdn.items
from educsdn.items import EducsdnItem
class CoursesSpider(scrapy.Spider):
name = 'courses'
allowed_domains = ['edu.csdn.net']
start_urls = ['https://edu.csdn.net/courses/o280_k/p1']
page = 1
def parse(self, response):
# 解析課程信息
dlist =response.selector.css("div.course_item")
# 遍歷課程信息並封裝到item
for dd in dlist:
item = EducsdnItem()
item['title'] = dd.css("span.ellipsis-2::text").extract_first()
item['url'] = dd.css("a::attr(href)").extract_first() #屬性用attr class直接用名字
item['pic'] = dd.css("img::attr(src)").extract_first()
item['teacher'] = dd.css("span.lecname::text").extract_first()
item['time'] = dd.css("span.course_lessons::text").extract_first()
item['price'] = dd.css("i::text").extract_first()
yield item
self.page += 1
if self.page < 3:
next_url = 'https://edu.csdn.net/courses/o280_k/p'+str(self.page)
url = response.urljoin(next_url)
yield scrapy.Request(url=url,callback=self.parse)
可以通過代碼運行結果看到,確實採集到了這部分信息。
下面是入庫對比:
入庫前後,這裏有一個問題在於價格的獲取都是None,目測有兩部分原因,一個是爬蟲體內的price選取條件不夠準確
,另一個是目標對象中有一部分是會員免費觀看課程,所以價格欄沒有。前者可以通過代碼調試和優化採集規則,後者可以通過異常數據等進行處理。
代碼放在github上了,首頁個人簡介中有。
調整了下代碼,將數據過濾了一下,重新跑了一遍。新數據有點好看!
好,這部分練習就到這裏,具體代碼,放入github上了。
還是那一句!刻意練習,每日精進!衝吧!