1. 程式人生 > >day26 -爬蟲-selenium、phantonJs

day26 -爬蟲-selenium、phantonJs

一、圖片懶載入

圖片懶載入概念:

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

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

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

二.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  
#建立瀏覽器物件,通過該物件可以操作瀏覽器
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名字查詢
from selenium import webdriver
import time
#1.建立一個瀏覽器物件
bro = webdriver.Chrome(executable_path=r"C:\Users\Administrator\Desktop\爬蟲02\chromedriver.exe")

#2.開啟瀏覽器
url = 'https://www.baidu.com/'
bro.get(url=url)
time.sleep(3)

#3.呼叫seleniem提供的介面
#找到了指定搜尋框
myInput = bro.find_element_by_id("kw")
#在對應的搜尋框中錄入指定的詞條
myInput.send_keys("人民幣")
time.sleep(5)
#定位到搜尋按鈕
myButton = bro.find_element_by_id('su')
myButton.click()

time.sleep(5)

#關閉瀏覽器
bro.quit()
示例1

三.phantomJs

  • PhantomJS是一款無介面的瀏覽器,其自動化操作流程和上述操作谷歌瀏覽器是一致的。由於是無介面的,為了能夠展示自動化操作流程,PhantomJS為使用者提供了一個截圖的功能,使用save_screenshot函式實現。
  • from selenium import webdriver
    import time
    
    # 1.建立一個瀏覽器物件
    # bro = webdriver.Chrome(executable_path=r"C:\Users\Administrator\Desktop\爬蟲02\chromedriver.exe")
    bro = webdriver.PhantomJS(executable_path=r"F:\Python自動化21期\3.Django&專案\phantomjs-2.1.1-windows\bin\phantomjs.exe")
    # 2.開啟瀏覽器
    url = 'https://www.baidu.com/'
    bro.get(url=url)
    time.sleep(3)
    # 截圖
    bro.save_screenshot('./1.png')
    # 3.呼叫seleniem提供的介面
    # 找到了指定搜尋框
    myInput = bro.find_element_by_id("kw")
    # 在對應的搜尋框中錄入指定的詞條
    myInput.send_keys("人民幣")
    time.sleep(5)
    bro.save_screenshot('./2.png')
    # 定位到搜尋按鈕
    myButton = bro.find_element_by_id('su')
    myButton.click()
    
    time.sleep(5)
    bro.save_screenshot('./3.png')
    # 關閉瀏覽器
    bro.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()
      豆瓣
       
    • #需求:梨視訊中爬取更多的視訊資料(動態載入)
    • 思路:通過js加載出更多的資料,獲取資料來源碼資料,對彈出的視訊資料進行解析(對url發起請求,獲取二級頁面的頁面資料),對獲取的圖片找到對應的js程式碼進行視訊資料的載入(介面開發者模式開啟輸入mp4)!
    • #需求:爬取更多的視訊資料(動態載入)
      import requests
      from selenium import webdriver
      from lxml import etree
      import re
      #1.建立一個無頭瀏覽器
      bro = webdriver.PhantomJS(executable_path=r"F:\Python自動化21期\3.Django&專案\phantomjs-2.1.1-windows\bin\phantomjs.exe")
      
      #2.根據指定的url開啟瀏覽器
      bro.get(url="http://www.pearvideo.com/category_6")
      
      #3.滾輪向下拖動,加載出更多的視訊資料(執行js程式碼)
      js = "window.scrollTo(0,document.body.scrollHeight)"
      bro.execute_script(js) #讓瀏覽器執行一組js程式碼
      
      #4.獲取頁面原始碼資料,進行解析操作
      page_text = bro.page_source#該屬性可以獲得當前瀏覽器對應的頁面資料
      
      #使用xpath進行解析操作
      tree = etree.HTML(page_text)
      li_list = tree.xpath('//li[@class="categoryem"]')
      headers = {
          'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36'
      }
      for li in li_list:
          secondPage_url = "http://www.pearvideo.com/"+li.xpath('./div/a/@href')[0]#./div 點表示定位到當前,一定要加
          #對上述url發起請求,獲取二級頁面的頁面資料
          page_text = requests.get(url=secondPage_url,headers=headers).text#獲取的圖片路徑
          video_url = re.findall('srcUrl="(.*?)",',page_text,re.S)[0] #S將整個頁面原始碼當做一個字串,正則作用於一整個大字串! srcUrl中內容是想要資料,可以加一個括號進行分組!
          videoData = requests.get(url=video_url,headers=headers).content
          fileName = video_url.split('/')[-1]
          with open(fileName,'wb') as fp:
              fp.write(videoData)
              print(fileName+'已經被下載完畢')
          
      pear

      四.谷歌無頭瀏覽器

      • 由於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'F:\selenium週末精品班\安裝包\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()
        擷取百度介面