Selenium爬取Ajax网站原理及方法看这一篇就够了

361 阅读5分钟

我正在参加「掘金·启航计划」

AJAX是什么?

AJAX = Asynchronous JavaScript And XML

AJAX 不是一种编程语言。

AJAX 仅使用以下组合:

  • 浏览器内置 XMLHttpRequest 对象(从 Web 服务器请求数据)
  • JavaScript 和 HTML DOM(显示或使用数据)

(AJAX 是一个具有误导性的名称。 AJAX 应用程序可能使用 XML 来传输数据,但以纯文本或 JSON 文本的形式传输数据同样常见。)

AJAX 允许通过在后台与 Web 服务器交换数据来异步更新网页。这意味着可以更新网页的部分内容,而无需重新加载整个页面。

AJAX工作流

image-20221005000521583

爬取AJAX网站的数据:

  • 普通爬虫程序流程:

image-20221004121005272

  • selenium爬虫程序流程:

image-20221004121209977

Selenium准备

Selenium是一个自动化测试工具,利用她可以驱动浏览器执行特定的动作,同时还可以获取浏览器当前呈现的页面内容,做到可见即可爬。

安装ChromeDriver

1.查看浏览器版本

帮助->关于Google Chrome

2.安装

3.验证

命令提示符窗口中输入"chromedriver",按下回车键,有starting开头的信息,表明ChromeDriver的环境变量配置成功。

selenium库的使用

  1. 声明浏览器对象(声明浏览器对象前须安装对应的浏览器和驱动)

from selenium import webdriver brower = webdriver.Chrome() brower = webdriver.Firefox() brower = webdriver.Edge()

  1. 访问网页 brower = get(URL)

浏览器对象提供的获取网页信息的属性和方法

属性和方法说 明
page_source获取当前页面 HTML 源代码
current_url获取当前页面 URL
title获取当前页面 HTML 源代码中 title 标签的文本信息
get_cookies()获取所有 cookie
get_cookie(name)获取指定cookie
add_cookie({})添加cookie,参数为字典类型
delete_all_cookies()删除所有 cookie
delete_cookie(name)删除指定 cookie
  1. 定位节点

selenium库提供的常用的定位节点的方法

方 法说 明
find_elemen(By.CLASS_NAME,"class name")通过节点的 class 属性值定位
find_element(By.NAME,"name")通过节点的 name 属性名定位
find_element(By.ID,"id")通过节点的 id 属性值定位
find_element(By.LINK_TEXT,"link_text")通过超链接节点的文本定位
find_element(By.PARTIAL_LINK_TEXT,"partial link text")通过超链接节点包含的部分文本定位
find_element(By.TAG_NAME, "tag name")通过节点名定位
find_element(By.XPATH, "xpath")使用 XPath 语法定位
find_element(By.CSS_SELECTOR, "css selector")使用 CSS 选择器定位

页面定位元素的策略

把方法名中的"element"改为"elements",匹配的将是所有符合条件的节点,返回一个list。调用方法定位到节点后回返回一个WebElement类型的对象。

WebElement对象提供的方法

方 法
get_attribute()获取属性
text获取文本
tag_name获取标签名
id获取节点 id
  1. 模拟浏览器操作

Selenium库提供的模拟浏览器操作的常用方法

对象 方法 说明
节点 send_kwys(string) 输入文字,参数类型为字符串
clear() 清除文字
click() 单击节点
浏览器 maximize_window() 最大化浏览器窗口
minimize_window() 最小化浏览器窗口
forward() 页面前进
back() 页面后退
refresh() 页面刷新
switch_to 切换窗口或嵌套页面
close()/quit() 关闭浏览器

键盘和鼠标命令

1、键盘输入动作 有些元素例如<input type=:"text">文本输入框是用户可以输入文字的,WebElement对象可以模拟用户的键盘输入动作,主要动作有:

  • 函数clear()模以清除element元素中的所有文字;
  • 函数send_keys(string)模拟键盘在元素中输入字符串string;其中send_keys函数不但可以模拟输入一般的文字,而且还可以模拟输入回车、退格等键盘动作,selenium提供了一个Keys类,其中提供了很多常用的不可见的特殊按键,主要有Keys.BACKSPACE退格删除键和Keys.ENTER回车键。

2、鼠标点击动作 很多HTML元素都有鼠标。点击动作,例如提交按钮点击后就提交表单。

  • WebElement使用click()函数实现鼠标点击,例如: driver.find_element_by_xpath("input[@type='submit']").click()

页面等待

  • 在浏览器加载网页的过程中,网页的有些元素时常会有延迟的现象,在HTML元素还没有准备好的情况下去操作这个HTML元素必然会出现错误,这个时候Selenium需要等待HTML元素。
  • Selenium强制等待

    # 设置强制等待1.5秒
    time.sleep(1.5)
    

很多网页采用了Ajax技术,程序无法确定某个节点是否已经完全加载。Selenium库提供了显式等待和隐式等待两种方式。

  • Selenium隐性等待

    # 设置隐性加载时间1.5秒
    driver.implicitly_wait(1.5)
    
  • Selenium显示等待

    waitTime=0
    while waitTime<10:
    marks =  driver.find_elements(By.XPATH,"//select/option")
    if len(marks)>0:
        break
        time.sleep(0.5)
        waitTime+=0.5
    if waitTime>=10:
        raise Exception("Waiting time out")
    

selenium库提供了WebDriverWait类实现显式等待,WebDriverWait的语法格式

WebDriverWait(driver,timeout,poll_frequency=0.5,ignored_exceptions=None)

WebDriverWait类须与until()方法或until_not()方法结合使用。

selenium库的expected_conditions类提供了until()方法和until_not()方法中预期条件判断的方法。

locator = (By.XPATH,"//select/option")
WebDriverWait(driver,10,0.5).until(EC.presence_of_element_located(locator))

等待方法

  1. EC.presence_of_element_located(locator) 这种形式是等待locator指定的元素出现,也就是HTML文档中建立起了这个元素。

  2. EC.visibility_of_element_located(locator) 这种形式是等待locator指定的元素可见,注意元素出现时未见得是可见的。

    例如:<select id="xmark" style="display:none">...</select>

  3. EC.element_to_be_clickable(locator) 这种形式是等待locator指定的元素可以被点击,例如在爬虫程序中等待按钮可用被点击:

    locator =(By.XPATH,"//input[@type='submit']")
    WebDriverWait(driver,10,0.5).until(EC.element_to_be_clickable(locator))
    
  4. EC.element_located_to_be_selected(locator) 这种形式是等待locator指定的元素可以被选择,可以被选择的元素一般是<select>中的<option>、<input type="checkbox">以及<input type="radio">等元素。

  5. EC.text_to_be_present_in_element(locator,text) 这种形式是等待locator:指定的元素的文本中包含指定的text文本,例如爬虫程序中使用下列的等待:

    locator =(By.ID,"msg")
    WebDriverWait(driver,10,0.5).until(EC.text_to_be_present_in_element(locator,"beauty"))