搜索引擎;
網站遷移;
數據整理、分析、統計;
跨域、第三方API調用;
還有,嗯釣魚網站啊;
......css
curl是利用URL語法在命令行方式下工做的開源文件傳輸工具。它被普遍應用在Unix、多種Linux發行版中,而且有DOS和Win3二、Win64下的移植版本
Shell:html
curl https://www.segmentfault.com
PHP:curl_init();
Java:URLConnection;
Python:requests模塊;
Node:http模塊;
...python
沒法獲取由Js腳本動態生成的網頁信息-
當今Web技術的大環境下,爲了網站的性能、可擴展性、用戶友好等方向,幾乎全部的Web頁面都在使用瀏覽器腳本動態生成內容,因此若是沒有腳本執行環境就沒有數據。git
無頭瀏覽器相似於在流行的Web瀏覽器的環境中提供對網頁的自動控制,但經過命令行接口或使用網絡通訊來執行。它們特別適用於測試網頁,由於它們可以以瀏覽器相同的方式呈現和解釋HTML,包括頁面佈局、顏色、字體選擇和JavaScript和Ajax的執行等樣式元素,當使用其它測試方法時,這些元素一般是不可用的
引自Wikipedia Headless browser
簡單來講就是用瀏覽器來對目標URL進行HTML解析,CSS渲染,Js執行,藉由API甚至能夠模擬用戶行爲(鼠標點擊,鍵盤輸入),但不提供UI渲染。github
經過以上咱們能夠知道Headless browser就是咱們想要的爬蟲方式了,本文旨在探討網頁爬蟲故不對其它用途特性作過多說明。web
Phantomjs(項目暫封存,慎用);
Chrome;
FireFox;ajax
Python + Selenium + ChromeDriverchrome
語法簡單,有各類成熟擴展庫,爬蟲周邊的庫能夠輕易找到shell
Selenium-主要是爲了自動化測試Web應用程序,但不侷限於此-
一句話解釋:控制瀏覽器,作任何想作的事情。(鼠標點擊、拖拽;用戶輸入,表單填充;History and Location API;Cookie;彈出對話框;定位和操做UI元素,執行JavaScript腳本)所以獲取經過ajax渲染的頁面的數據就不是什麼難事了:)
附 Documentation編程
如上所述,Selenium能夠操做瀏覽器,可是須要藉助ChromeDriver它是實現 WebDriver 有線協議的一個開源工具,它提供了導航到網頁、用戶輸入、JavaScript執行等等的能力。ChromeDriver經過chrome的自動代理框架控制瀏覽器
如下將經過兩個小例子來了解Selenium :)
文件名:searchPython.py
from selenium import webdriver # 從selenium導入webdriver driver = webdriver.Chrome() # Optional argument, if not specified will search path. driver.get('https://www.baidu.com') # 獲取百度頁面
Shell:
py searchPython.py
chromeDriver屬性及方法
顯示以下:
input = driver.find_element_by_id('kw') #獲取輸入框 searchButton = driver.find_element_by_id('su') #獲取搜索按鈕
經常使用查找元素方法:
查看經常使用定位元素方法
注:find_element_by_ 將獲取 find_elements_by_ 的第一個元素,獲取到的元素會被包裝爲 WebElement 對象
以上定位元素方法還能夠經過以下方式實現:
from selenium.webdriver.common.by import By #支持的定位器策略集 driver.find_element(By.ID,'kw') driver.find_element(By.ID,'su') '''註釋 策略集以下: CLASS_NAME = 'class name' CSS_SELECTOR = 'css selector' ID = 'id' LINK_TEXT = 'link text' NAME = 'name' PARTIAL_LINK_TEXT = 'partial link text' TAG_NAME = 'tag name' XPATH = 'xpath' '''
inputElement.send_keys("Python") #輸入框輸入"Python" searchButton.click() #搜索
WebElement屬性及事件API
顯示以下:
from selenium import webdriver # 從selenium導入webdriver driver = webdriver.Chrome() # Optional argument, if not specified will search path. driver.get('https://www.baidu.com') # 獲取百度頁面 inputElement = driver.find_element_by_id('kw') #獲取輸入框 searchButton = driver.find_element_by_id('su') #獲取搜索按鈕 inputElement.send_keys("Python") #輸入框輸入"Python" searchButton.click() #搜索
這裏涉及兩個概念:
顯式等待(Explicit Waits)-
在給定的條件函數返回True以前,設置一個最長等待時間,和重複執行給定條件函數的間隔時間,若是條件函數在規定時間內返回True則即刻繼續執行,不然將拋出一個異常!
隱式等待(Implicit Waits)
告訴WebDriver在試圖找到一個元素或元素時,若是它們沒有當即可用,則會在必定時間內對DOM進行輪詢,默認設置爲0,一旦設置,就爲WebDevor對象實例的生命週期設置隱式等待。
文件名:bilibili.py
from selenium import webdriver from selenium.webdriver.support.wait import WebDriverWait # 用於實例化一個Driver的顯式等待 from selenium.webdriver.common.by import By # 內置定位器策略集 from selenium.webdriver.support import expected_conditions as EC # 內置預期條件函數,具體API請參考此小節後API連接 driver = webdriver.Chrome() driver.get('https://www.bilibili.com/v/game/esports/?spm_id_from=333.334.primary_menu.35#/9222') try: WebDriverWait(driver, 20, 0.5).until(EC.presence_of_all_elements_located((By.CLASS_NAME,'vd-list'))) #使用expected_conditions自帶驗證函數 for doctorName in driver.find_elements_by_css_selector('.vd-list li'): print(doctorName.find_element_by_css_selector('.r > a').text) finally: driver.close() # close the driver
構造器,接受一個Driver實例,超時時長(秒),執行條件函數的間隔時間。用於實例化一個Driver的顯式等待
方法:
1.until(method, message='')
調用第一個參數給定的函數,直到函數不返回False,除了能夠接受expected_conditions內置預期條件函數還能夠自定義函數,以下
例:
def hasDoctors(d): # 自定義條件函數 when the function is called , the first prms will be a driver if (len(d.find_elements_by_css_selector('.vd-list li'))): return True return False WebDriverWait(driver, 20, 0.5).until(hasDoctors) # 自定義函數形式
2.until_not(method, message='')
與until相反
支持的內置的預期條件,簡稱EC,以下:
title_is:判斷當前頁面的title是否徹底等於(==)預期字符串
title_contains:判斷當前頁面的title是否包含預期字符串
presence_of_element_located:判斷某個元素是否被加到了dom樹裏,並不表明該元素必定可見
visibility_of_element_located:判斷某個元素是否可見,可見表明元素非隱藏,而且元素的寬和高都不等於0
visibility_of:與上述的方法同樣,區別是上述方法要傳入元祖locator即(By.ID,'kw'),此方法直接傳定位到的WebElement
presence_of_all_elements_located:判斷是否至少有1個元素存在於dom樹中,有則返回WebElements列表
text_to_be_present_in_element:判斷元素的text是否包含預期字符串
text_to_be_present_in_element_value:判斷元素的value屬性是否包含預期字符串
frame_to_be_available_and_switch_to_it:檢查給定幀是否可切換到,若是能夠,則將給定的驅動器切換到指定的iframe
......
這裏包含了全部的預置條件說明
運行Shell以下: