爬蟲之圖片懶加載技術,selenium

 

一 . 圖片懶加載技術

  案例分析:抓取站長素材http://sc.chinaz.com/中的圖片數據

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)#打印圖片名稱

  運行結果發現,咱們能夠獲取到圖片名稱,可是獲取到的連接爲空,這就是圖片懶加載的緣由

  圖片懶加載的概念:

圖片懶加載是一種網頁優化技術,當你請求網頁的時候,若是全部圖片一下全加載出來會影響網頁加載效率的,
爲了解決這個問題,先後端協同工做,使圖片在瀏覽器當前窗口才加載出來,達到減小首屏圖片請求次數,這種就稱爲圖片懶加載

  網站通常實現圖片懶加載的技術

在網頁源碼中,在img標籤中首先會使用這個'僞屬性'(一般使用src2,original...)去存放真正的連接,
當圖片出現到可視化窗口的時候,會動態的替換成src屬性,完成圖片加載

  經過細緻觀察頁面的結構後發現,網頁中圖片的連接是存儲在了src2這個僞屬性中

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/@src2') #src2僞屬性 image_name = div.xpath('.//img/@alt') print(image_url) #打印圖片連接 print(image_name)#打印圖片名稱

二 . selenium

  爲何要使用selenium?

有些網站的數據是動態加載的,若是用requests是不能獲取到數據的,用selenium經過驅動瀏覽器,徹底模擬瀏覽器操做,好比下拉,單擊,跳轉等,這樣就能夠獲取到數據

  環境安裝

下載安裝selenium:pip install selenium 下載瀏覽器驅動程序: http://chromedriver.storage.googleapis.com/index.html 查看驅動和瀏覽器版本的映射關係: http://blog.csdn.net/huilan_same/article/details/51896672

  操做前須要知道的知識

# 元素定位
find_element_by_id() find_element_by_name() find_element_by_class_name() find_element_by_tag_name() find_element_by_link_text() find_element_by_partial_link_text() find_element_by_xpath() find_element_by_css_selector()

  簡單使用與效果展現

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

  上述的class和id都是經過網頁源代碼找到的

  -- 來一個有經常使用的功能簡易版使用

from selenium import webdriver from time import sleep # 使用谷歌瀏覽器,填寫瀏覽器驅動位置
driver = webdriver.Chrome(r'./chromedriver.exe') # 打開網址用get
bro = driver.get('http://www.baidu.com') sleep(2) # 找到搜索框的id
content_input = driver.find_element_by_id('kw') # 輸入內容
content_input.send_keys('庫裏') sleep(2)
# 清空用clear() # content_input.clear()
#
找到搜索按鈕的id btn = driver.find_element_by_id('su') btn.click() sleep(3) # 退出 driver.quit()

  執行js代碼

from selenium import webdriver from time import sleep # 使用谷歌瀏覽器,填寫瀏覽器驅動位置
driver = webdriver.Chrome(r'./chromedriver.exe') driver.get('https://xueqiu.com') sleep(3) # 實現滾輪向下滑動,第一個參數是橫向滾輪,第二個參數是縱向
js = 'window.scrollTo(0,document.body.scrollHeight)'
# 執行js代碼
driver.execute_script(js) sleep(2) # 每執行一次就向下滑動一下
driver.execute_script(js) sleep(2) # 這樣就能獲取到動態加載的數據了
print(driver.page_source) # 退出
driver.quit()

   谷歌無頭瀏覽器,是一款無界面的谷歌瀏覽器

# 谷歌無頭瀏覽器,不出現可視化界面
from selenium import webdriver from selenium.webdriver.chrome.options import Options from time import sleep # 建立一個參數對象,用來控制chrome以無界面模式打開
chrome_options = Options() chrome_options.add_argument('--headless') chrome_options.add_argument('--disable-gpu') # 使用谷歌瀏覽器,填寫瀏覽器驅動位置
browser = webdriver.Chrome(executable_path=r'./chromedriver.exe', options=chrome_options) # 打開網址用get
bro = browser.get('http://www.baidu.com') sleep(2) # 找到搜索框的id
content_input = browser.find_element_by_id('kw') # 輸入內容
content_input.send_keys('庫裏') sleep(2) # 找到搜索按鈕的id
btn = browser.find_element_by_id('su') btn.click() sleep(3) # 截屏,沒啥意義 # browser.save_screenshot('./curry.png')

# 退出
browser.quit()

  向前和後退

import time from selenium import webdriver browser=webdriver.Chrome(r'./chromedriver.exe') browser.get('https://www.baidu.com') browser.get('https://www.taobao.com') browser.get('http://www.sina.com.cn/') browser.back() time.sleep(2) browser.forward() time.sleep(2) browser.close()

  動做鏈(鼠標拖拽,鍵盤按鍵,這些動做的執行就是動做鏈)

from selenium import webdriver from selenium.webdriver import ActionChains import time browser = webdriver.Chrome() url = 'http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable' browser.get(url) # 當定位標籤存在iframe的時候須要用到switch_to
browser.switch_to.frame('iframeResult')  # 裏面是id # 初識位置
source = browser.find_element_by_id('#draggable') # 結束位置
target = browser.find_element_by_id('#droppable') # 建立一個動做鏈的對象
action = ActionChains(browser) action.drag_and_drop(source,target) # 執行動做鏈
aciton.perform() sleep(3) # 能夠模擬人的拖動效果,慢慢的拖動 # 點擊長按 # actions.click_and_hold(source) # time.sleep(3) # for i in range(5): # # perform表示開始執行動做鏈 # action.move_by_offset(xoffset=17,yoffset=0).perform() # time.sleep(0.5)
 browser.quit()

  selenium規避檢測

如今很多大網站有對selenium採起了監測機制。好比正常狀況下咱們用瀏覽器訪問淘寶等網站的 window.navigator.webdriver的值爲 undefined。
而使用selenium訪問則該值爲true。

  解決辦法

from selenium.webdriver import Chrome from selenium.webdriver import ChromeOptions option = ChromeOptions() option.add_experimental_option('excludeSwitches', ['enable-automation']) driver = Chrome(r'瀏覽器驅動程序路徑',options=option) # 其餘操做不用變,再去console一下window.navigator.webdriver就顯示undefined了
相關文章
相關標籤/搜索