Ajax形式的請求時JS動態渲染的一種手段,我們可以通過requests和urllib庫來實現頁面數據抓取,但是js動態渲染頁面不僅僅是AJAX一種形式,
有的網頁是由JS直接生成的,並非原始HTML,可能還不包含AJAX請求;例如一些報表工具ECharts 官網的實例,圖形都是通過JS生成的;例如淘寶頁面,即使是AJAX請求數據,但是接口中包含了很多加密參數,我們很難以找到規則,也因此很難分析AJAX請求來抓取數據;
為了解決以上問題,我們可以直接通過使用模擬瀏覽器運行的方式實現,那么就可以實現原本瀏覽器中可以看到的,抓取的數據就是什么樣,即所見即所"得"(爬);此時我們不用再去關心網頁中JS使用了什么算法或者結構實現了頁面渲染,不用關心網頁后台的AJAX接口到底有哪些參數;
Python提供了好多模擬瀏覽器運行的庫,例如:Seleium,Splash,PyV8,Ghost等;
Selenium的使用
Selenium是一個自動化測試工具,可以按照指定的命令自動操作;
安裝: pip install selenium
官網:http://www.seleniumhq.org
中文文檔:http://selenium-python-zh.readthedocs.io
由於Selenium需要啟動瀏覽器,因此需要安裝不同瀏覽器的驅動;
1.chromedriver 下載地址:https://code.google.com/p/chromedriver/downloads/list
2.Firefox的驅動geckodriver 下載地址:https://github.com/mozilla/geckodriver/releases/
3.IE的驅動IEdriver 下載地址:http://www.nuget.org/packages/Selenium.WebDriver.IEDriver/
例如火狐瀏覽器如下安裝方式:
下載解壓后,將chromedriver.exe , geckodriver.exe , Iedriver.exe發到Python的安裝目錄,例如 D:\python 。這里我們只用了火狐瀏覽器為例,
則將 geckodriver.exe 放入python根目錄;然后再將Python的安裝目錄添加到系統環境變量的Path下即可;
這里我放在了:D:\Programs\Python\Python37\Scripts目錄,且之前已經在Path下設置了該目錄的環境變量;
測試是否安裝成功,如果執行后打開一個對應瀏覽器的空白頁,則表示安裝成功;
火狐瀏覽器啟動:
1 from selenium import webdriver 2 browser = webdriver. Firefox()
谷歌瀏覽器啟動:
1 from selenium import webdriver 2 3 browser = webdriver.Chrome()
IE瀏覽器啟動:
1 from selenium import webdriver 2 3 browser = webdriver.Ie()
注:此方法有不便之處,即在程序運行過程中需要一直開着瀏覽器,在爬取網頁過程中瀏覽器可能一直開啟,目前Chrome瀏覽器版本已經支持無界面模式了,如果版本比較舊此時就不會支持無界面模式;
還有另一種方式,即安裝一個無界面瀏覽器PhantomJS,此時抓取過程都會在后台運行,不會再彈出瀏覽器窗口了;
1.瀏覽器對象聲明:
Selenium支持非常多的瀏覽器,例如Chrome、Firefox、Edge等,還有Android,BlackBerry等手機端的瀏覽器;也支持無界面的PhantomJS;
例如:
from selenium import webdriver
browser = webdri ver. Chrome()
browser = webdriver. Firefox()
browser = webdri ver. Edge()
browser = webdriver. PhantomJS()
browser= webdriver.Safari()
2.瀏覽器對象訪問資源
可以通過get()方法請求頁面,參數傳入連接URL即可;
1 from selenium import webdriver 2 browser = webdriver. Firefox() 3 browser.get('https://www.baidu.com') 4 print(browser.page_source) 5 browser.close()
3、查找節點
Selenium可以驅動瀏覽器完成各種操作,例如:填充表單,模擬單擊事件等;
比如我們想通過程序添加表單數據,需要知道保單在那個位置;但是Selenium提供了一系列查找節點的方法,我們可以利用這些方法獲取節點,做下一步執行動作和信息抓取做准備;
例如:
1 from selenium import webdriver 2 browser = webdriver. Firefox() 3 browser.get('https://www.baidu.com') 4 input_1=browser.find_element_by_id('kw')#百度輸入框的id為kw 5 input_2=browser.find_element_by_css_selector('#kw')#按照css選擇器選擇對象 6 input_3=browser.find_element_by_xpath('//*[@id="kw"]')#按照xml path選擇元素 7 8 9 print(input_1) 10 print(input_2) 11 print(input_3) 12 browser.close()
find_element()方法:
該方法有兩個參數,表示查找方式by和值;即:find_element_by_id('id值') 等價find_element(By.ID,'id值')
是一種通用的查找方法;
find_elements()方法:
該方法用於多個節點的查找,比上面方法多了個s字母,
例如:
browser.find_elements_by_class_name
browser.find_element_by_class_name
兩個方法,一個帶s一個不帶,則前者是查找多個節點,后者只找一個節點;
1 news_menus1=browser.find_elements(By.CSS_SELECTOR,'.mnav') 2 news_menus2=browser.find_elements(By.CLASS_NAME,'mnav')
4、節點交互
Selenium 可以驅動瀏覽器來執行一些動作,即讓瀏覽器模擬執行一些動作;常見用法:
輸入文字時用send_keys()方法,清空文字則使用clear()方法,點擊按鈕則click()方法;
例如:先輸入Python關鍵詞,然后清空,在輸入JAVA,點擊按鈕訪問;此時為了看到更好效果,則加入休眠5秒;
1 from selenium import webdriver 2 import time 3 from selenium.webdriver.common.by import By 4 browser = webdriver. Firefox() 5 browser.get('https://www.baidu.com') 6 input_1=browser.find_element_by_id('kw')#百度輸入框的id為kw 7 input_1.send_keys('Python') 8 time.sleep(5) 9 input_1.clear() 10 input_1.send_keys('JAVA') 11 time.sleep(5) 12 suBtn=browser.find_element_by_id('su') 13 suBtn.click() 14 15 browser.close()
5、動作鏈
上面實例是通過點擊觸發的事件,例如鼠標拖拽,鍵盤按鍵燈,這些動作需要通過另一種方式執行,即所謂的動作鏈;
鼠標事件:
事件 |
描述 |
context_click() |
鼠標右擊 |
double_click() |
鼠標雙擊 |
drag_and_drop(source,target) |
拖動 |
move_to_element() |
光標懸停 |
move_to |
移動 |
鍵盤事件:
事件 |
描述 |
send_keys(Keys.BACK_SPACE) |
刪除按鍵 |
send_keys(Keys.SPACE) |
空格鍵 |
send_keys(Keys.TAB) |
Tab鍵 |
send_keys(Keys.ESCAPE) |
ESC鍵 |
send_keys(Keys.ENTER) |
回車鍵 |
send_keys(Keys.CONTROL,'a') |
A |
send_keys(Keys.CONTROL,'c') |
C |
send_keys(Keys.CONTROL,'x') |
X |
send_keys(Keys.CONTROL,'v') |
V |
... |
... |
send_keys(Keys.F1) |
F1 |
send_keys(Keys.F5) |
F5 |
send_keys(Keys.F12) |
F12 |
... |
... |
例如: