15天學會爬蟲 第八天

爬蟲

第八天

scrapy框架流程

scrapy框架流程

其流程可以描述如下:

  1. 調度器把requests–>引擎–>下載中間件—>下載器

  2. 下載器發送請求,獲取響應---->下載中間件---->引擎—>爬蟲中間件—>爬蟲

  3. 爬蟲提取數據,分爲兩類:

    • 提取的是url地址,組裝成request對象---->爬蟲中間件—>引擎—>調度器

    • 提取數據—>引擎—>管道

  4. 管道進行數據的處理和保存

注意:

  • 圖中綠色線條的表示數據的傳遞
  • 注意圖中中間件的位置,決定了其作用
  • 注意其中引擎的位置,所有的模塊之前相互獨立,只和引擎進行交互

scrapy的入門使用

  1. 創建工程

    scrapy startproject pro_name(工程名稱)

  2. 創建爬蟲文件

    cd pro_name

    srcapy genspider spider_name allowed_domain

  3. 找spdier_name.py文中完成爬蟲代碼

    class ItcastSpider(scrapy.Spider):
        name = 'itcast' # 爬蟲名
        allowed_domains = ['itcast.cn'] # 允許爬去的域名範圍
        start_urls = ['http://www.itcast.cn/channel/teacher.shtml'] # 起始的url
    
        def parse(self, response): # start_url發請求後的響應的處理函數
            li_list = response.xpath("//div[@class='tea_con']/div/ul/li")
            for li in li_list:
                item = {}
                item['name'] = li.xpath(".//h3/text()").extract_first()
                item['title'] = li.xpath(".//h3/text()").extract_first()
                item['desc'] = li.xpath(".//p/text()").extract_first()
                print(item) # none,request,item ,dict
    

    如果parse函數不存在,會觸發父類scrapy.Spider中的parse函數,拋出異常

    def parse(self, response):
    raise NotImplementedError('{}.parse callback is not defined'.format(self.__class__.__name__))
    

    關於extract()extract_first()的使用

    • response.xpath() 返回的是一個特殊列表,該列表具有extract()和extract_first()方法
    # 特殊列表返回的元素項是 Selector對象 <Selector xpath="//div[@class='tea_con']/div/ul/li//h3/text()" data='朱老師'>
    ret = response.xpath("//div[@class='tea_con']/div/ul/li//h3/text()")
    
    # 如果要提取想要的數據
    ret.extract() # 從ret特殊列表中出去每個selector的data值,放入新列表
    
    • 如果由於xpath寫的有問題,導致返回的列表爲空,從中獲取字符串數據時,可以使用 extract_first()

      ret.extract_first() # 判斷ret列表的長度,如果長度爲0,返回None,否則取出列表第0項的元素selector中的data屬性值並返回
      
  4. 啓動爬蟲

    scrapy crawl spider_name

yield作用

yield出現在函數中,將函數提升爲一個生成器,調用test()會返回一個生成器對象(不會執行函數代碼),當調用生成器的next時候,函數會在執行遇到yield的時候返回,再次調用next的時候,會從上次yield的位置繼續執行,直到遇到下一次的yield

def test():
    print("***************")
    for i in range(10):
        print("-------------")
        yield i
        print("++++++++++++++")

a = test()
x = next(a)
print(x)

y = next(a)
print(y)

** 生成器是一種特殊的迭代器 **

管道 PIpline

  1. 創建管道對象,在piplines.py中

    class MyspiderPipeline(object):
        def process_item(self, item, spider): # 被引擎調用,傳遞數據item和爬蟲對象
            if spider.name == "itcast":
                print(item)
            return item  # 如果存在多個管道的情況下,必須有,否則下一個管道接不到數據item
    
  2. 開啓管道,在配置文件中開啓管道

    ITEM_PIPELINES = {
       'myspider.pipelines.MyspiderPipeline': 300, # 300表示當前管道處理數據優先級,數字越小,優先級越高
    }
    
  3. 將爬蟲的數據通過yield的方式交給引擎,引擎再交給管道

    class ItcastSpider(scrapy.Spider):
        name = 'itcast'
        allowed_domains = ['itcast.cn']
        start_urls = ['http://www.itcast.cn/channel/teacher.shtml']
    
        def parse(self, response):
            li_list = response.xpath("//div[@class='tea_con']/div/ul/li//h3/text()")
            for li in li_list:
                item = {}
                item['name'] = li.xpath(".//h3/text()").extract_first()
                item['title'] = li.xpath(".//h3/text()").extract_first()
                item['desc'] = li.xpath(".//p/text()").extract_first()
                yield item  # none,request,item ,dict
    

配置文件基本使用

設置日誌等級

LOG_LEVEL = "WARNING"
# 一般情況下,不建議設置“Waring”,很多造成爬蟲抓取數據失敗的原因都是在DEBUG等級顯示的,設置爲WARNING就不會顯示了

設置UA

# Crawl responsibly by identifying yourself (and your website) on the user-agent
USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36'

構造請求

  • scrapy.Request(url,callback,meta,dont_filter)

    • url:請求地址,必須是完整的url地址
    • callback:該請求對應的響應的處理函數
    • meta:在不同的解析函數中進行數據傳遞
    • dont_filter:默認時False,即過濾請求,scrapy框架默認會過濾重複的請求,相同url的請求只進行一次,第二次會被調度器攔截過濾掉
  • response.follow(url,callback)

    • url:請求地址,可以不完整,該方法會自動補充完整
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章