圖片懶加載技術
一. 案例分析:抓取站長素材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)#打印圖片名稱
二. 利用selenuim 模擬瀏覽器滑動到底部, 加載數據.
class ProductSpider(scrapy.Spider):
name = "Product1688"
start_urls = []
def __init__(self, **kwargs):
# 加載 chrome driver, 它的下載地址位於 https://sites.google.com/a/chromium.org/chromedriver/
super().__init__(**kwargs)
self.driver = webdriver.Chrome('/path/to/your/chromedriver')
self.wait = WebDriverWait(self.driver, 10)
def parse(self, response):
self.driver.get(response.url)
# 打開頁面后,滑動至頁面底部
self.scroll_until_loaded()
# 以 xpath 尋找商品名(標題 )
title = self.driver.find_element_by_xpath('//*[@id="mod-detail-title"]/h1')
# 以 xpath 尋找商品主圖片
main_images_elements = self.driver.find_elements_by_xpath('//*[@id="dt-tab"]/div/ul/li/div/a/img')
# 以 xpath 尋找商品詳情圖片
detail_images_elements = \
self.driver.find_elements_by_xpath('//*[@id="desc-lazyload-container"]/p/span/strong/img')
item = ProductItem()
main_images = []
detail_images = []
# 獲取商品主圖的網絡地址,針對商品主圖片尺寸的特殊處理
for image in main_images_elements:
main_images.append(image.get_attribute('src').replace('60x60.', ''))
# 獲取商品詳情圖片的網絡地址
for image in detail_images_elements:
detail_images.append(image.get_attribute('src'))
item['title'] = title.text
item['main_image_count'] = len(main_images)
item['image_urls'] = main_images + detail_images
return item
# 模擬瀏覽器頁面滾到頁面底部的行為
def scroll_until_loaded(self):
check_height = self.driver.execute_script("return document.body.scrollHeight;")
while True:
self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
try:
self.wait.until(
lambda driver: self.driver.execute_script("return document.body.scrollHeight;") > check_height)
check_height = self.driver.execute_script("return document.body.scrollHeight;")
except TimeoutException:
break