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 |