一.什麼是圖片懶載入?
案例分析:抓取站長素材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標籤中設定一個偽屬性,去存放正式的圖片連結而並非直接存放在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)#列印圖片名稱
3.phantomJS
phantomJS是一款無介面的瀏覽器,其自動化操作流程和上述操作谷歌瀏覽器是一致的,由於是無介面的,為了能夠展示自動化流程,phantomJS提供了截圖功能,使用sace_sreenshot函式實現.
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()
4.谷歌無頭瀏覽器
- 由於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()