動態網頁爬蟲
什么是動態網頁爬蟲和AJAX技術:
- 動態網頁,是網站在不重新加載的情況下,通過ajax技術動態更新網站中的局部數據。比如拉勾網的職位頁面,在換頁的過程中,url是沒有發生改變的,但是職位數據動態的更改了。
- AJAX(Asynchronouse JavaScript And XML)異步JavaScript和XML。前端與服務器進行少量數據交換,Ajax 可以使網頁實現異步更新。這意味着可以在不重新加載整個網頁的情況下,對網頁的某部分進行更新。傳統的網頁(不使用Ajax)如果需要更新內容,必須重載整個網頁頁面。因為傳統的在傳輸數據格式方面,使用的是XML語法。因此叫做AJAX,其實現在數據交互基本上都是使用JSON。使用AJAX加載的數據,即使使用了JS,將數據渲染到了瀏覽器中,在右鍵->查看網頁源代碼還是不能看到通過ajax加載的數據,只能看到使用這個url加載的html代碼。
動態網頁爬蟲的解決方案:
- 直接分析ajax調用的接口。然后通過代碼請求這個接口。
- 使用Selenium+chromedriver模擬瀏覽器行為獲取數據。
selenium和chromedriver:
使用selenium關閉瀏覽器:
- driver.close():關閉當前的頁面。
- driver.quit():關閉整個瀏覽器。
selenium定位元素:
- find_element_by_id:根據id來查找某個元素。
- find_element_by_class_name:根據類名查找元素。
- find_element_by_name:根據name屬性的值來查找元素。
- find_element_by_tag_name:根據標簽名來查找元素。
- find_element_by_xpath:根據xpath語法來獲取元素。
- find_element_by_css_selector:根據css選擇器選擇元素。
要注意,find_element是獲取第一個滿足條件的元素。find_elements是獲取所有滿足條件的元素。


selenium表單操作:
- webelement.send_keys:給輸入框填充內容。
- webelement.click:點擊。
- 操作select標簽:需要首先用
from selenium.webdriver.support.ui import Select來包裝一下選中的對象,才能進行select選擇:- select_by_index:按索引進行選擇。
- select_by_value:按值進行選擇。
- select_by_visible_text:按照可見文本進行選擇。
selenium行為鏈:
有時候在頁面中的操作可能要有很多步,那么這時候可以使用鼠標行為鏈類selenium.webdriver.common.action_chains.ActionChains來完成。比如現在要將鼠標移動到某個元素上並執行點擊事件。那么示例代碼如下:
inputTag = driver.find_element_by_id('kw')
submitTag = driver.find_element_by_id('su')
actions = ActionChains(driver)
actions.move_to_element(inputTag)
actions.send_keys_to_element(inputTag,'python')
actions.move_to_element(submitTag)
actions.click(submitTag)
actions.perform()
還有更多的鼠標相關的操作。
click_and_hold(element):點擊但不松開鼠標。
context_click(element):右鍵點擊。
double_click(element):雙擊。
下面是B站的登錄和拖拉驗證滑條。

下面是鍵盤操作

設置瀏覽器的參數是在定義driver的時候設置chrome_options參數,該參數是一個Options類所實例化的對象。
其中的參數是設置瀏覽器是否可視化和請求頭等信息。

瀏覽器多窗口切換是在同一個瀏覽器中切換不同的網頁窗口。

Selenium提供了一些延時功能
隱形等待是在一個設定的時間內檢測網頁是否加載完成,也就是瀏覽器標簽欄的小圈不再轉才會執行下一步。
顯性等待能夠根據判斷條件而進行靈活等待,程序每隔一定時間檢測一次,如果結果和檢測條件成立了會執行下一步。顯性等待的使用涉及多個模塊:
By:設置元素定位方式。分別是ID、XPATH、LINK_TEXT、NAME等等。
expected_conditions:驗證網頁元素是否存在。
WebDriverWait的參數說明如下:driver:瀏覽器對象driver;timeout:超時時間;poll_frequency:檢測時間間隔;
ignored_exceptions:忽略的異常。until:條件判斷,參數必須為expected_conditions對象。

更多方法請參考:http://selenium-python.readthedocs.io/api.html
為什么需要行為鏈條?
因為有些網站可能會在瀏覽器端做一些驗證行為是否符合人類的行為來做反爬蟲。這時候我們就可以使用行為鏈來模擬人的操作。行為鏈有更多的復雜操作,比如雙擊,右鍵等,在自動化測試中非常有用。
操作cookie:
- 獲取所有的cookie:
for cookie in driver.get_cookies(): print(cookie) - 根據cookie的key獲取value:
value = driver.get_cookie(key) - 刪除所有的cookie:
driver.delete_all_cookies() - 刪除某個cookie:
driver.delete_cookie(key) - 添加cookie:
driver.add_cookie({“name”:”username”,”value”:”abc”})

隱式等待和顯式等待:
- 隱式等待:指定一個時間,在這個時間內一直會處於等待狀態。隱式等待需要使用
driver.implicitly_wait。 - 顯式等待:指定在某個時間內,如果某個條件滿足了,那么就不會再等待,如果在指定的時間內條件都不滿足,那么就不會再等待了。顯式等待用的方法是
from selenium.webdriver.support.ui import WebDriverWait。示例代碼如下:driver.get("https://kyfw.12306.cn/otn/leftTicket/init?linktypeid=dc") WebDriverWait(driver,100).until( EC.text_to_be_present_in_element_value((By.ID,"fromStationText"),"長沙") ) WebDriverWait(driver,100).until( EC.text_to_be_present_in_element_value((By.ID,"toStationText"),"北京") ) btn = driver.find_element_by_id("query_ticket") btn.click()
打開新窗口和切換頁面:
- selenium中沒有專門的打開新窗口的方法,是通過
window.execute_script()來執行js腳本的形式來打開新窗口的。window.execute_script("window.open('https://www.douban.com/')") - 打開新的窗口后
driver當前的頁面依然還是之前的,如果想要獲取新的窗口的源代碼,那么就必須先切換過去。示例代碼如下:window.switch_to.window(driver.window_handlers[1])
設置代理:
設置代理通過ChromeOptions來設置,示例代碼如下:
options = webdriver.ChromeOptions()
options.add_argument("--proxy-server=http://110.52.235.176:9999")
driver = webdriver.Chrome(executable_path="D:\ProgramApp\chromedriver\chromedriver73.exe",chrome_options=options)
driver.get("http://httpbin.org/ip")
補充:
- get_property:獲取html標簽中官方寫好的屬性。
- get_attribute:獲取html標簽中官方和非官方的屬性。
- driver.save_screenshoot:獲取當前頁面的截圖,有時候請求失敗了,那么可以把當前網頁的截圖保存下來,方便后期進行分析。
