1. 程式人生 > >爬蟲之圖片懶載入技術、selenium和PhantomJS

爬蟲之圖片懶載入技術、selenium和PhantomJS

爬蟲之圖片懶載入技術、selenium和PhantomJS

 
  • 圖片懶載入
  • selenium
  • phantomJs
  • 谷歌無頭瀏覽器

 

一.圖片懶載入

  • 什麼是圖片懶載入?
    • 案例分析:抓取站長素材http://sc.chinaz.com/中的圖片資料
      #!/usr/bin/env python
      # -*- coding:utf-8 -*-
      import requests
      from lxml import etree if __name__ == "__main__": url = 'http://sc.chinaz.com/tupian/gudianmeinvtupian.html' headers = { 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36', } #獲取頁面文字資料 response = requests.get(url=url,headers=headers) response.encoding = 'utf-8' page_text = response.text #解析頁面資料(獲取頁面中的圖片連結) #建立etree物件 tree = etree.HTML(page_text) div_list = tree.xpath('//div[@id="container"]/div') #解析獲取圖片地址和圖片的名稱 for div in div_list: image_url = div.xpath('.//img/@src') image_name = div.xpath('.//img/@alt') print(image_url) #列印圖片連結 print(image_name)#列印圖片名稱

       

    • - 執行結果觀察發現,我們可以獲取圖片的名稱,但是連結獲取的為空,檢查後發現xpath表示式也沒有問題,究其原因出在了哪裡呢?

    • 圖片懶載入概念:

      • 圖片懶載入是一種網頁優化技術。圖片作為一種網路資源,在被請求時也與普通靜態資源一樣,將佔用網路資源,而一次性將整個頁面的所有圖片載入完,將大大增加頁面的首屏載入時間。為了解決這種問題,通過前後端配合,使圖片僅在瀏覽器當前視窗內出現時才載入該圖片,達到減少首屏圖片請求數的技術就被稱為“圖片懶載入”。

    • 網站一般如何實現圖片懶載入技術呢?

      • 在網頁原始碼中,在img標籤中首先會使用一個“偽屬性”(通常使用src2,original......)去存放真正的圖片連結而並非是直接存放在src屬性中。當圖片出現到頁面的視覺化區域中,會動態將偽屬性替換成src屬性,完成圖片的載入。

    • 站長素材案例後續分析:通過細緻觀察頁面的結構後發現,網頁中圖片的連結是儲存在了src2這個偽屬性中

      #!/usr/bin/env python
      # -*- coding:utf-8 -*-
      import requests
      from lxml import etree if __name__ == "__main__": url = 'http://sc.chinaz.com/tupian/gudianmeinvtupian.html' headers = { 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36', } #獲取頁面文字資料 response = requests.get(url=url,headers=headers) response.encoding = 'utf-8' page_text = response.text #解析頁面資料(獲取頁面中的圖片連結) #建立etree物件 tree = etree.HTML(page_text) div_list = tree.xpath('//div[@id="container"]/div') #解析獲取圖片地址和圖片的名稱 for div in div_list: image_url = div.xpath('.//img/@src'2) #src2偽屬性 image_name = div.xpath('.//img/@alt') print(image_url) #列印圖片連結 print(image_name)#列印圖片名稱

       

二.selenium

  • 什麼是selenium?
    • 是Python的一個第三方庫,對外提供的介面可以操作瀏覽器,然後讓瀏覽器完成自動化的操作。  

  • 環境搭建

    • 安裝selenum:pip install selenium

    • 獲取某一款瀏覽器的驅動程式(以谷歌瀏覽器為例)

      • 谷歌瀏覽器驅動下載地址:http://chromedriver.storage.googleapis.com/index.html

      • 下載的驅動程式必須和瀏覽器的版本統一,大家可以根據http://blog.csdn.net/huilan_same/article/details/51896672中提供的版本對映表進行對應

               效果展示:

from selenium import webdriver
from time import sleep

# 後面是你的瀏覽器驅動位置,記得前面加r'','r'是防止字元轉義的 driver = webdriver.Chrome(r'驅動程式路徑') # 用get開啟百度頁面 driver.get("http://www.baidu.com") # 查詢頁面的“設定”選項,並進行點選 driver.find_elements_by_link_text('設定')[0].click() sleep(2) # # 開啟設定後找到“搜尋設定”選項,設定為每頁顯示50條 driver.find_elements_by_link_text('搜尋設定')[0].click() sleep(2) # 選中每頁顯示50條 m = driver.find_element_by_id('nr') sleep(2) m.find_element_by_xpath('//*[@id="nr"]/option[3]').click() m.find_element_by_xpath('.//option[3]').click() sleep(2) # 點選儲存設定 driver.find_elements_by_class_name("prefpanelgo")[0].click() sleep(2) # 處理彈出的警告頁面 確定accept() 和 取消dismiss() driver.switch_to_alert().accept() sleep(2) # 找到百度的輸入框,並輸入 美女 driver.find_element_by_id('kw').send_keys('美女') sleep(2) # 點選搜尋按鈕 driver.find_element_by_id('su').click() sleep(2) # 在開啟的頁面中找到“Selenium - 開源中國社群”,並開啟這個頁面 driver.find_elements_by_link_text('美女_百度圖片')[0].click() sleep(3) # 關閉瀏覽器 driver.quit()

程式碼介紹:

#導包
from selenium import webdriver  
#建立瀏覽器物件,通過該物件可以操作瀏覽器
browser = webdriver.Chrome('驅動路徑')
#使用瀏覽器發起指定請求
browser.get(url)

#使用下面的方法,查詢指定的元素進行操作即可
    find_element_by_id            根據id找節點
    find_elements_by_name         根據name找
    find_elements_by_xpath        根據xpath查詢
    find_elements_by_tag_name     根據標籤名找
    find_elements_by_class_name   根據class名字查詢

 

 

三.phantomJs

  • PhantomJS是一款無介面的瀏覽器,其自動化操作流程和上述操作谷歌瀏覽器是一致的。由於是無介面的,為了能夠展示自動化操作流程,PhantomJS為使用者提供了一個截圖的功能,使用save_screenshot函式實現。
  • 程式碼演示:
    from selenium import webdriver
    import time
    
    # phantomjs路徑
    path = r'PhantomJS驅動路徑'
    browser = webdriver.PhantomJS(path)
    
    # 開啟百度
    url = 'http://www.baidu.com/'
    browser.get(url)
    
    time.sleep(3)
    
    browser.save_screenshot(r'phantomjs\baidu.png')
    
    # 查詢input輸入框
    my_input = browser.find_element_by_id('kw')
    # 往框裡面寫文字
    my_input.send_keys('美女')
    time.sleep(3)
    #截圖
    browser.save_screenshot(r'phantomjs\meinv.png')
    
    # 查詢搜尋按鈕
    button = browser.find_elements_by_class_name('s_btn')[0]
    button.click()
    
    time.sleep(3)
    
    browser.save_screenshot(r'phantomjs\show.png')
    
    time.sleep(3)
    
    browser.quit()

     

  • 重點:selenium+phantomjs 就是爬蟲終極解決方案:有些網站上的內容資訊是通過動態載入js形成的,所以使用普通爬蟲程式無法回去動態載入的js內容。例如豆瓣電影中的電影資訊是通過下拉操作動態載入更多的電影資訊。

    • 綜合操作:需求是儘可能多的爬取豆瓣網中的電影資訊

      from selenium import webdriver
      from time import sleep
      import time
      
      if __name__ == '__main__':
          url = 'https://movie.douban.com/typerank?type_name=%E6%81%90%E6%80%96&type=20&interval_id=100:90&action='
          # 發起請求前,可以讓url表示的頁面動態加載出更多的資料
          path = r'C:\Users\Administrator\Desktop\爬蟲授課\day05\ziliao\phantomjs-2.1.1-windows\bin\phantomjs.exe'
          # 建立無介面的瀏覽器物件
          bro = webdriver.PhantomJS(path)
          # 發起url請求
          bro.get(url)
          time.sleep(3)
          # 截圖
          bro.save_screenshot('1.png')
      
          # 執行js程式碼(讓滾動條向下偏移n個畫素(作用:動態載入了更多的電影資訊))
          js = 'window.scrollTo(0,document.body.scrollHeight)'
          bro.execute_script(js)  # 該函式可以執行一組字串形式的js程式碼
          time.sleep(2)
      
          bro.execute_script(js)  # 該函式可以執行一組字串形式的js程式碼
          time.sleep(2)
          bro.save_screenshot('2.png') 
          time.sleep(2) 
          # 使用爬蟲程式爬去當前url中的內容 
          html_source = bro.page_source # 該屬性可以獲取當前瀏覽器的當前頁的原始碼(html) 
          with open('./source.html', 'w', encoding='utf-8') as fp: 
              fp.write(html_source) 
          bro.quit()

       

四.谷歌無頭瀏覽器

  • 由於PhantomJs最近已經停止了更新和維護,所以推薦大家可以使用谷歌的無頭瀏覽器,是一款無介面的谷歌瀏覽器。
  • 程式碼展示:
    from selenium import webdriver
    from selenium.webdriver.chrome.options import Options
    import time
     
    # 建立一個引數物件,用來控制chrome以無介面模式開啟
    chrome_options = Options()
    chrome_options.add_argument('--headless')
    chrome_options.add_argument('--disable-gpu')
    # 驅動路徑
    path = r'C:\Users\ZBLi\Desktop\1801\day05\ziliao\chromedriver.exe'
     
    # 建立瀏覽器物件
    browser = webdriver.Chrome(executable_path=path, chrome_options=chrome_options)
     
    # 上網
    url = 'http://www.baidu.com/'
    browser.get(url)
    time.sleep(3)
     
    browser.save_screenshot('baidu.png')
     
    browser.quit()

 

  • 圖片懶載入
  • selenium
  • phantomJs
  • 谷歌無頭瀏覽器

 

一.圖片懶載入

  • 什麼是圖片懶載入?
    • 案例分析:抓取站長素材http://sc.chinaz.com/中的圖片資料
      #!/usr/bin/env python
      # -*- coding:utf-8 -*-
      import requests
      from lxml import etree if __name__ == "__main__": url = 'http://sc.chinaz.com/tupian/gudianmeinvtupian.html' headers = { 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36', } #獲取頁面文字資料 response = requests.get(url=url,headers=headers) response.encoding = 'utf-8' page_text = response.text #解析頁面資料(獲取頁面中的圖片連結) #建立etree物件 tree = etree.HTML(page_text) div_list = tree.xpath('//div[@id="container"]/div') #解析獲取圖片地址和圖片的名稱 for div in div_list: image_url = div.xpath('.//img/@src') image_name = div.xpath('.//img/@alt') print(image_url) #列印圖片連結 print(image_name)#列印圖片名稱

       

    • - 執行結果觀察發現,我們可以獲取圖片的名稱,但是連結獲取的為空,檢查後發現xpath表示式也沒有問題,究其原因出在了哪裡呢?

    • 圖片懶載入概念:

      • 圖片懶載入是一種網頁優化技術。圖片作為一種網路資源,在被請求時也與普通靜態資源一樣,將佔用網路資源,而一次性將整個頁面的所有圖片載入完,將大大增加頁面的首屏載入時間。為了解決這種問題,通過前後端配合,使圖片僅在瀏覽器當前視窗內出現時才載入該圖片,達到減少首屏圖片請求數的技術就被稱為“圖片懶載入”。

    • 網站一般如何實現圖片懶載入技術呢?

      • 在網頁原始碼中,在img標籤中首先會使用一個“偽屬性”(通常使用src2,original......)去存放真正的圖片連結而並非是直接存放在src屬性中。當圖片出現到頁面的視覺化區域中,會動態將偽屬性替換成src屬性,完成圖片的載入。

    • 站長素材案例後續分析:通過細緻觀察頁面的結構後發現,網頁中圖片的連結是儲存在了src2這個偽屬性中

      #!/usr/bin/env python
      # -*- coding:utf-8 -*-
      import requests
      from lxml import etree if __name__ == "__main__": url = 'http://sc.chinaz.com/tupian/gudianmeinvtupian.html' headers = { 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36', } #獲取頁面文字資料 response = requests.get(url=url,headers=headers) response.encoding = 'utf-8' page_text = response.text #解析頁面資料(獲取頁面中的圖片連結) #建立etree物件 tree = etree.HTML(page_text) div_list = tree.xpath('//div[@id="container"]/div') #解析獲取圖片地址和圖片的名稱 for div in div_list: image_url = div.xpath('.//img/@src'2) #src2偽屬性 image_name = div.xpath('.//img/@alt') print(image_url) #列印圖片連結 print(image_name)#列印圖片名稱

       

二.selenium

  • 什麼是selenium?
    • 是Python的一個第三方庫,對外提供的介面可以操作瀏覽器,然後讓瀏覽器完成自動化的操作。  

  • 環境搭建

    • 安裝selenum:pip install selenium

    • 獲取某一款瀏覽器的驅動程式(以谷歌瀏覽器為例)

      • 谷歌瀏覽器驅動下載地址:http://chromedriver.storage.googleapis.com/index.html

      • 下載的驅動程式必須和瀏覽器的版本統一,大家可以根據http://blog.csdn.net/huilan_same/article/details/51896672中提供的版本對映表進行對應

               效果展示:

from selenium import webdriver
from time import sleep

# 後面是你的瀏覽器驅動位置,記得前面加r'','r'是防止字元轉義的 driver = webdriver.Chrome(r'驅動程式路徑') # 用get開啟百度頁面 driver.get("http://www.baidu.com") # 查詢頁面的“設定”選項,並進行點選 driver.find_elements_by_link_text('設定')[0].click() sleep(2) # # 開啟設定後找到“搜尋設定”選項,設定為每頁顯示50條 driver.find_elements_by_link_text('搜尋設定')[0].click() sleep(2) # 選中每頁顯示50條 m = driver.find_element_by_id('nr') sleep(2) m.find_element_by_xpath('//*[@id="nr"]/option[3]').click() m.find_element_by_xpath('.//option[3]').click() sleep(2) # 點選儲存設定 driver.find_elements_by_class_name("prefpanelgo")[0].click() sleep(2) # 處理彈出的警告頁面 確定accept() 和 取消dismiss() driver.switch_to_alert().accept() sleep(2) # 找到百度的輸入框,並輸入 美女 driver.find_element_by_id('kw').send_keys('美女') sleep(2) # 點選搜尋按鈕 driver.find_element_by_id('su').click() sleep(2) # 在開啟的頁面中找到“Selenium - 開源中國社群”,並開啟這個頁面 driver.find_elements_by_link_text('美女_百度圖片')[0].click() sleep(3) # 關閉瀏覽器 driver.quit()

程式碼介紹:

#導包
from selenium import webdriver  
#建立瀏覽器物件,通過該物件可以操作瀏覽器
browser = webdriver.Chrome('驅動路徑')
#使用瀏覽器發起指定請求
browser.get(url)

#使用下面的方法,查詢指定的元素進行操作即可
    find_element_by_id            根據id找節點
    find_elements_by_name         根據name找
    find_elements_by_xpath        根據xpath查詢
    find_elements_by_tag_name     根據標籤名找
    find_elements_by_class_name   根據class名字查詢

 

 

三.phantomJs

  • PhantomJS是一款無介面的瀏覽器,其自動化操作流程和上述操作谷歌瀏覽器是一致的。由於是無介面的,為了能夠展示自動化操作流程,PhantomJS為使用者提供了一個截圖的功能,使用save_screenshot函式實現。
  • 程式碼演示:
    from selenium import webdriver
    import time
    
    # phantomjs路徑
    path = r'PhantomJS驅動路徑'
    browser = webdriver.PhantomJS(path)
    
    # 開啟百度
    url = 'http://www.baidu.com/'
    browser.get(url)
    
    time.sleep(3)
    
    browser.save_screenshot(r'phantomjs\baidu.png')
    
    # 查詢input輸入框
    my_input = browser.find_element_by_id('kw')
    # 往框裡面寫文字
    my_input.send_keys('美女')
    time.sleep(3)
    #截圖
    browser.save_screenshot(r'phantomjs\meinv.png')
    
    # 查詢搜尋按鈕
    button = browser.find_elements_by_class_name('s_btn')[0]
    button.click()
    
    time.sleep(3)
    
    browser.save_screenshot(r'phantomjs\show.png')
    
    time.sleep(3)
    
    browser.quit()

     

  • 重點:selenium+phantomjs 就是爬蟲終極解決方案:有些網站上的內容資訊是通過動態載入js形成的,所以使用普通爬蟲程式無法回去動態載入的js內容。例如豆瓣電影中的電影資訊是通過下拉操作動態載入更多的電影資訊。

    • 綜合操作:需求是儘可能多的爬取豆瓣網中的電影資訊

      from selenium import webdriver
      from time import sleep
      import time
      
      if __name__ == '__main__':
          url = 'https://movie.douban.com/typerank?type_name=%E6%81%90%E6%80%96&type=20&interval_id=100:90&action='
          # 發起請求前,可以讓url表示的頁面動態加載出更多的資料
          path = r'C:\Users\Administrator\Desktop\爬蟲授課\day05\ziliao\phantomjs-2.1.1-windows\bin\phantomjs.exe'
          # 建立無介面的瀏覽器物件
          bro = webdriver.PhantomJS(path)
          # 發起url請求
          bro.get(url)
          time.sleep(3)
          # 截圖
          bro.save_screenshot('1.png')
      
          # 執行js程式碼(讓滾動條向下偏移n個畫素(作用:動態載入了更多的電影資訊))
          js = 'window.scrollTo(0,document.body.scrollHeight)'
          bro.execute_script(js)  # 該函式可以執行一組字串形式的js程式碼
          time.sleep(2)
      
          bro.execute_script(js)  # 該函式可以執行一組字串形式的js程式碼
          time.sleep(2)
          bro.save_screenshot('2.png') 
          time.sleep(2) 
          # 使用爬蟲程式爬去當前url中的內容 
          html_source = bro.page_source # 該屬性可以獲取當前瀏覽器的當前頁的原始碼(html) 
          with open('./source.html', 'w', encoding='utf-8') as fp: 
              fp.write(html_source) 
          bro.quit()

       

四.谷歌無頭瀏覽器

  • 由於PhantomJs最近已經停止了更新和維護,所以推薦大家可以使用谷歌的無頭瀏覽器,是一款無介面的谷歌瀏覽器。
  • 程式碼展示:
    from selenium import webdriver
    from selenium.webdriver.chrome.options import Options
    import time
     
    # 建立一個引數物件,用來控制chrome以無介面模式開啟
    chrome_options = Options()
    chrome_options.add_argument('--headless')
    chrome_options.add_argument('--disable-gpu')
    # 驅動路徑
    path = r'C:\Users\ZBLi\Desktop\1801\day05\ziliao\chromedriver.exe'
     
    # 建立瀏覽器物件
    browser = webdriver.Chrome(executable_path=path, chrome_options=chrome_options)
     
    # 上網
    url = 'http://www.baidu.com/'
    browser.get(url)
    time.sleep(3)
     
    browser.save_screenshot('baidu.png')
     
    browser.quit()