08.Python網絡爬蟲之圖片懶加載技術、selenium和PhantomJS

引入

今日概要css

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

知識點回顧html

  • 驗證碼處理流程

今日詳情python

動態數據加載處理web

一.圖片懶加載chrome

  • 什麼是圖片懶加載?
    • 案例分析:抓取站長素材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表達式也沒有問題,究其緣由出在了哪裏呢?windows

    • 圖片懶加載概念:後端

      • 圖片懶加載是一種網頁優化技術。圖片做爲一種網絡資源,在被請求時也與普通靜態資源同樣,將佔用網絡資源,而一次性將整個頁面的全部圖片加載完,將大大增長頁面的首屏加載時間。爲了解決這種問題,經過先後端配合,使圖片僅在瀏覽器當前視窗內出現時才加載該圖片,達到減小首屏圖片請求數的技術就被稱爲「圖片懶加載」。api

    • 網站通常如何實現圖片懶加載技術呢?瀏覽器

      • 在網頁源碼中,在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名字查找 

# 獲取搜索結果,定位有效數據的位置或表單框架
find_element(self,by='id',value=None) # 取第一個符合條件的值
find_elements(self,by='id',value=None) # 取全部符合條件的值
這兩個函數能夠替代下面全部函數,如find_element(by='id',value='abc') == find_element_by_id("abc")

 
      

find_element_by_class_name(self,name)
find_element_by_css_selector(self,css_selector)
find_element_by_id(self,id)
find_element_by_link_text(self,link_text)
find_element_by_name(self,name)
find_element_by_partial_link_text(self,link_text)
find_element_by_tag_name(self,name)
find_element_by_xpath(self,xpath)

 
      


# 查找文本框
textElement = browser.find_element_by_class_name("s_ipt")
textElement = browser.find_element_by_id("kw")

 
      

textElement.clear()
textElement.send_keys("python selenium")

 
      

# 查找提交按扭
submitElement = browser.find_element_by_class_name("btn self-btn bg s_btn")
submitElement = browser.find_element_by_id("su")
submitElement.click()
print browser.title

 
      


# 定位有效數據
resultElements = browser.find_elements_by_class_name("c-tools")
len(resultElements)

 
      

# 通常來講定位結果用by_xpath或by_css比較方便
# 從位置中獲取有效數據
element.text
element.get_attribute(name)

 
      

value = resultElements[0].get_attribute("data-tools")
valueDic = eval(value)

 
      

print valueDic.get("title").decode("utf8")
print valueDic.get("url")

 

 

三.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()

     

相關文章
相關標籤/搜索