AJAX
對於靜態網頁來說,在你發出請求的時候會請求全部的資源,而對於網頁資源涉及較多,有一部分資源加載較慢的網頁來說,等所有的資源全部加載完畢之後才顯示整個網頁的策略則會大大影響用戶的使用。而動態網頁則可以避免這個問題。
異步 JavaScript 和 XML(Asynchronouse JacaScript and XML)能夠在後臺與服務器進行少量的數據交換,從而可以使網頁實現異步更新,這樣就可以在不重新加載整個頁面的情況下,對網頁的數據進行更新,通過 AJAX 加載的數據可以通過 JSON 將數據直接渲染到瀏覽器中。
獲取 AJAX 數據
和之前利用 Cookie 信息保持登陸狀態一樣,獲取 AJAX 動態加載的數據也有兩種方法:
- 直接分析 AJAX 調用的接口,然後通過代碼發送請求
- 使用 Selenium 模擬瀏覽器行爲獲取數據
兩種方法的優缺點爲:
方式 | 優點 | 缺點 |
分析接口 | 可以直接獲取數據,不需要進行解析,代碼量少,性能高 | 接口分析比較複雜 |
selenium | 模擬瀏覽器的行爲,更加穩定 | 代碼量多,性能低 |
Selenium
chromedriver
chromedriver 相當於是一個驅動 chrome 瀏覽器的驅動程序,使用該驅動能夠驅動瀏覽器正常工作。國內有 chromedriver 的鏡像可供下載,對於不同的瀏覽器有不同的驅動,可以根據自己瀏覽器自行下載。
Selenium
selenium 可以模擬用戶在瀏覽器上的行爲,比如點擊,輸入等,從而達到自動的效果。
基本使用
from selenium import webdriver
import time
# chromedriver 的路徑
driver_path = r'D:\chromedriver\chromedriver.exe'
# 要訪問的網頁
url = r'https://www.baidu.com/'
# 初始化 driver
driver = webdriver.Chrome(executable_path=driver_path)
# 通過 driver 請求 url
driver.get(url)
# 等待
time.sleep(5)
# 退出瀏覽器
driver.quit()
之後 chromedriver 便能夠自動打開 chrome 訪問指定頁面,等待 5 秒後退出。
常用操作
函數 | 描述 | 示例 |
close() | 關閉當前頁面 | dirver.close() |
quit() | 退出瀏覽器 | dirver.quit() |
find_element() | 獲取第一個滿足條件的元素 | dirver.find_element(By.ID,'su') |
find_elements() | 獲取所有滿足條件的元素 | dirver.find_element(By.ID,'su') |
find_element_by_id() | 根據 id 來查找元素 | dirver.find_element_by_id('su') |
find_element_by_class_name() | 根據類名查找元素 | dirver.find_element_by_class_name('name') |
find_element_by_name() | 根據 name 屬性值查找元素 | dirver.find_element_by_name('name') |
find_element_by_tag_name() | 根據標籤名查找元素 | dirver.find_element_by_tag_name('div') |
find_element_by_xpath() | 根據 xpath 語法查找元素 | dirver.find_element_by_xpath('//div') |
find_element_by_css_selector() | 根據 css 選擇器選擇元素 | dirver.find_element_by_css_selector('//div') |
send_keys() | 操作輸入框 |
input=driver.find_element_by_id('kw') input.send_keys('python') |
clear() | 清除輸入框內容 | input.clear() |
click() | 鼠標點擊 |
checkbox=driver.find_element_by_name('rememberMe') checkbox.click() |
click_and_hold(element) | 點擊但不鬆開鼠標 | |
context_click(element) | 鼠標右擊 | |
double_click(element) | 鼠標雙擊 | |
Select | 下拉列表的類 |
from selenium.webdriver.support.ui import Select tag=Select(driver.find_element_by_name('jumpMenu')) tag.select_by_index(1) # tag.select_by_value('value') # tag = select_by_visible_text('text') tag.deselect_all() |
ActionChain
如果某個操作需要使用很多步驟才能夠完成,此時需要藉助 ActionChain 來完成:
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()
cookie
函數 | 描述 | 示例 |
get_cookies() | 獲取所有 cookie | driver.get_cookies() |
get_cookie() | 根據 key 獲取 cookie 的 value | driver.get_cookie(key) |
delete_all_cookies() | 刪除所有 cookie | driver.delete_all_cookies() |
delete_cookie() | 根據 key 刪除 cookie | driver.delete_cookie(key) |
頁面等待
有時網頁加載的速度較慢,因爲不能在指定的元素加載之前就進行操作,因此此時需要進行頁面等待。等待分爲兩種:
- 隱式等待:調用 driver.implicitly_wait,此時在獲取到元素之前,會先等待 10 秒
driver = webdriver.Chrome(executable_path=driver_path)
driver.implicitly_wait(10)
driver.get("https://www.douban.com/")
- 顯式等待:此時在某個條件成立後才執行操作。也可以設置最大等待時間
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Firefox()
driver.get("http://somedomain/url_that_delays_loading")
try:
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "myDynamicElement"))
)
finally:
driver.quit()
其它的一些等待條件爲:
函數 | 描述 |
presence_of_element_located | 某個元素已經加載完畢 |
presence_of_all_emement_located | 網頁中所有滿足條件的元素都加載完畢 |
element_to_be_cliable | 某個元素可以點擊 |
切換頁面
如果需要切換頁面,可以使用 switch_to_window 進行切換,切換到的頁面則由 driver.window_handles 確定:
# 打開一個新的頁面
driver.execute_script("window.open('"+url+"')")
# 切換到這個新的頁面中
driver.switch_to_window(driver.window_handles[1])
設置代理
使用 selenium 設置代理的方法爲:
from selenium import webdriver
driver_path = r"D:\chromedriver\chromedriver.exe"
options = webdriver.ChromeOptions()
options.add_argument("--proxy-server=https://117.89.25.75:8118")
driver = webdriver.Chrome(executable_path=driver_path,chrome_options=options)
driver.get('http://httpbin.org/ip')
WebElement
該類是獲取元素的所屬類,常用屬性有:
get_attribute | 標籤的某個屬性值 |
screenshot | 獲取當前頁面的截圖,只能用於 driver |