【Python】WebUI自动化—Selenium的下载和安装、基本用法、项目实战(16)

文章目录

一.介绍

Selenium 是一个用于测试 Web 应用程序的自动化测试工具,它直接运行在浏览器中,实现了对浏览器的自动化操作,它支持所有主流的浏览器,包括 IE,Firefox,Safari,Chrome 等。

-支持所有主流平台(如,Windows、Linux、IOS、Android、Edge、Opera等)

实现了诸多自动化功能,比如软件自动化测试,检测软件与浏览器兼容性,自动录制、生成不同语言的测试脚本,以及自动化爬虫等。

  • Selenium 提供了一个工具集,包括 Selenium WebDriver(浏览器驱动)、Selenium IDE(录制测试脚本)、Selenium Grid(执行测试脚本)。后面两个主要用于测试脚本的录制、执行,因此不做介绍。我们只对 Selenium WebDriver 做重点讲解。
    • 关于 Selenium IDE/Grid 的相关知识可参考官网文档
      • Selenium Grid 用于并行运行多个测试用例在不同的浏览器、操作系统和机器上
      • Selenium IDE 提供简易的界面,允许用户通过录制和回放操作来创建和执行自动化测试脚本。支持多种浏览器,包括Chrome、Firefox和Safari等,可以在这些浏览器上进行测试。

二.下载安装selenium

Linux、Mac 用户执行以下命令即可:

python 复制代码
pip install Selenium

Windows 用户执行以下命令即可实现安装:

python 复制代码
python -m pip install selenium

除了命令安装,也可以通过官网下载 Selenium WebDriver 安装包

三.安装浏览器驱动

Selenium 能够调用浏览器,必须通过浏览器驱动来实现。不同的浏览器需要使用不同驱动程序

以 Windows10 平台 Chrome 浏览器为例。先检查浏览器版本号,并下载相应驱动文件,然后解压文件,将 Chromedriver.exe 文件拷贝到 Python 安装目录的 Scripts 目录下,最后将其添加到系统环境变量中。

  • 查看 Python 安装路径:

    python 复制代码
    where python

    环境变量配置如下

    完成上述操作后,命令行启动驱动程序

    python 复制代码
    chromedriver
    • 开启成功后,驱动程序会在后台运行

四.QuickStart---自动访问百度

python 复制代码
# 导入seleinum webdriver接口
from selenium import webdriver
import time
# 创建Chrome浏览器对象
browser = webdriver.Chrome()
#访问百度网站
browser.get('http://www.baidu.com/')
#阻塞3秒
time.sleep(3)
# 自动退出浏览器
browser.quit()

如下所示

  • 经过测试,说明安装浏览器驱动可正常工作。Selenium WebDriver 实现了许多操作浏览器功能。比如实现自动点击、自动输入、自动搜索、自动登录等等。

  • -毫不夸张的说,Selenium 自动化爬虫是一种万能的爬虫程序,它可以仿照人的样子去打开网站,并拿到你想要的数据,因此你无须在意反爬措施。不过它最致命的缺点就是效率很低,因为每次点击、输入等操作都需要花费一定的时间,因此它仅适用于小批量的数据抓取

五.Selenium基本用法

1.定位节点

1.1.单个元素定位

Selenium 提供了 8 种定位单个节点的方法如下:

python 复制代码
from selenium import webdriver
from selenium.webdriver.common.by import By
# 初始化浏览器为谷歌浏览器
chr = webdriver.Chrome()

#通过 xpath 表达式定位
chr.find_element(By.XPATH, "//*[@id='search']")
#通过 class 属性值定位
chr.find_element(By.CLASS_NAME, "element_class_name")
#通过 id 属性值定位
chr.find_element(By.ID,"element_id")
#通过 name 属性值定位
chr.find_element(By.NAME, "element_name")
#通过<a>标签内文本定位,即精准定位。
chr.find_element(By.LINK_TEXT,"element_link_text")
#通过 css 选择器定位
chr.find_element(By.CSS_SELECTOR, "element_css_selector")
#	通过 tag 标签名定位
chr.find_element(By.TAG_NAME, "element_tag_name")
#通过<a>标签内部分文本定位,即模糊定位。
chr.find_element(By.PARTIAL_LINK_TEXT, "element_partial_link_text")



#旧版定位元素方法如下:
#chr.find_element_by_name()	
#chr.find_element_by_class_name()	
#chr.find_element_by_tag_name()
#chr.find_element_by_link_text()	
#chr.find_element_by_partial_link_text()	
#chr.find_element_by_xpath()	
#chr.find_element_by_css_selector()	
html 复制代码
<html>
<head>
<body link="#cc0916">
  <a id="logo" href="http://www.baidu.com" onclick="">
   <form id="form" class="fm" name="f" action="baidu.com">
    <span class="btn"></span>
    <input id="kw" class="s_ipt_wr" name="wd" value="" maxlength="255" autocomplete="off">
</body>
</head>
</html>

使用上面提供方法定位 input 输出框。如下所示:

python 复制代码
from selenium import webdriver
from selenium.webdriver.common.by import By
# 创建browser是浏览器对象
browser = webdriver.Chrome()
# 访问某个url得到上述代码片段
browser.get('url')
# 通过id定义输入框
browser.find_element(By.ID, "kw")
# 通过class定义
browser.find_element(By.CLASS_NAME, "s_ipt_wr")
# 通过name定位
browser.find_element(By.NAME, "wd")
# 通过tag name定位:
browser.find_element(By.TAG_NAME, "input")
# 通过xpath定位
browser.find_element(By.XPATH, "//*[@id='kw']")
# 通过css选择器定位
browser.find_element(By.CSS_SELECTOR, "#kw")

通过 a 标签内的文本内容定位节点,如下所示:

python 复制代码
<a class="vip" href="http://www.baidu.com">百度123</a>
<a class="search" href="http://www.google.com">谷歌456</a>
python 复制代码
#使用全部文本内容定位链接
browser.find_element(By.LINK_TEXT,"百度123")
#使用部分文本内容定位链接
browser.find_element(By.PARTIAL_LINK_TEXT,"456")

1.2.多个元素定位

与单个元素的定位方式类似,把find_element改成find_elements即可,返回值是一个列表,您可以使用 for 循环拿到所有的元素节点。

python 复制代码
from selenium import webdriver
from selenium.webdriver.common.by import By
# 初始化浏览器为谷歌浏览器
chr = webdriver.Chrome()

chr.find_elements(By.CLASS_NAME, "element_class_name")
chr.find_elements(By.ID,"element_id")

2.控制浏览器

Selenium 可以操控浏览器的窗口大小、刷新页面,以及控制浏览器的前进、后退等

2.1.设置浏览器窗口大小、位置

python 复制代码
from selenium import webdriver

driver1 = webdriver.Chrome()
driver1.get("http://www.baidu.com")

#参数数字为像素点
driver1.set_window_size(480, 800)
#设置窗口位置
driver1.set_window_position(100,200)
#同时设置窗口的大小和坐标
driver1.set_window_rect(450,300,32,50)
#退出浏览器
driver1.quit()

2.2.浏览器前进、刷新、后退、关闭

python 复制代码
from selenium import webdriver
driver2 = webdriver.Chrome()

# 访问C语言中文网首页
first_url= 'http://c.biancheng.net'
driver2.get(first_url)

# 访问c语言教程
second_url='http://c.biancheng.net/c/'
driver2.get(second_url)

# 返回(后退)到c语言中文网首页
driver2.back()
# 前进到C语言教程页
driver2.forward()
# 刷新当前页面相当于F5
driver2.refresh()
# 退出/关闭浏览器
driver2.quit()

3.3.等待

什么是等待?

  • 代码执行过程中,第一次未找到元素,先不抛出异常。激活等待时间,在等待过程中如果找到元素就执行

为什么要等待?

  • 由于网络或配置原因,导致元素未加载出来,而代码已执行,会触发异常

元素等待类型

  • 隐式等待
  • 显式等待
  • 强制等待--->time.slepp(秒)

隐式等待(针对全部元素生效

  • 定位元素时,如果能定位到元素则直接返回该元素, 不触发等待;
    • 如果不能定位到该元素,则间隔一段时间后再去定位元素;
    • 如果在达到最大时长时还没有找到指定元素,则抛出元素不存在的的异常NoSuchElementException
  • 方法:driver.implicitly_wait(秒)

提示:在项目中,如果未封装自动化框架时,推荐使用。

显示等待(`针对单个元素生效``)

  • 说明:针对单个元素生效,可以修改查找频率和超时时间

  • 特点:查找并返回元素。

  • 用法

    python 复制代码
    from selenium.webdriver.support.wait import WebDriverWait
    from selenium.webdriver.common.by import By
    #显式等待:返回查找到的元素
    el = WebDriverWait(driver, 10, 0.5).until(lambda x: x.find_element(By.XPATH, "/html/body/div[4]/div/div[2]/div[2]/ul/li[1]/div/div[1]/a/img"))
    el.click()

3.4.Frame

1.什么是frame框架?

  • 在当前页面的指定区域显示另外一个页面的内容。

2.frame表单切换的方法

  • 一般利用·id或name属性值切换·,有时frame标签没有id和name,则考虑·下标index和元素定位切换·。

  • 切换到指定frame

    • 方法: driver.switch_to.frame(frame_reference) : frame_reference可以为frame框架的name、id或者定位到的frame元素

      • 通过id切换:driver.switch_to.frame("id")
      • 通过name切换:driver.switch_to.frame("name")
      • 通过index下标切换:driver.switch_to.frame(0)----第一个下标是0
      • 通过元素切换:
      python 复制代码
      element = driver.find_element(By.XPATH,'iframe')
      driver.switch_to.frame(element)
  • 切换回默认页面

    • 方法:driver.switch_to.default_content()
    • 注意:必须先切换回默认页面,才可以继续在默认页面进行操作

代码示例

python 复制代码
#获取注册A iframe元素
element_A = driver.find_element(By.CSS_SELECTOR,"#idframe1")
#1、切换到A
driver.switch_to.frame(element_A)
#2、注册A操作
driver.find_element(By.CSS_SELECTOR,"#userA").send_keys("admin")

#3、回到默认目录
driver.switch_to.default_content()

#4、获取注册B iframe元素
element_B = driver.find_element(By.CSS_SELECTOR,"#idframe2")
#5、切换到B
driver.switch_to.frame(element_B)
#6、注册B操作
driver.find_element(By.CSS_SELECTOR,"#userB").send_keys("admin")

3.5.多窗口

  1. 为什么要切换?

    • selenium默认启动时,所有焦点在启动窗口,无法操作其他窗口
  2. 如何切换?

    python 复制代码
    driver.current_window_handle   #获取当前窗口句柄
    driver.window_handles  # 获取所有窗口句柄
    driver.switch_to.window(handle[n])  #切换指定句柄窗口
    • 注意:窗口句柄是一个唯一的标识符,可以用来定位浏览器的窗口。每次你打开一个新的窗口或标签,Selenium会为其创建一个新的窗口句柄.
  3. 示例

    python 复制代码
    # 1、获取浏览器(创建浏览器驱动对象)
    driver = webdriver.Chrome()
    # 2、输入URL,打开web页面
    driver.get("http://hmshop-test.itheima.net/Home/Goods/goodsList/id/5.html")
    driver.implicitly_wait(3)
    print("操作之前所有的窗口句柄:", driver.window_handles)
    driver.find_element(By.XPATH, "/html/body/div[4]/div/div[2]/div[2]/ul/li[1]/div/div[1]/a/img").click()
    handles = driver.window_handles
    print("操作之后所有的窗口句柄:", handles)
    # 切换窗口
    driver.switch_to.window(handles[1])
    # 将商品加入购物车
    driver.find_element(By.XPATH, "/html/body/div[3]/div/form/div/div[8]/div/a[2]").click()
    time.sleep(2)
    # 4、关闭浏览器驱动
    driver.quit()
    • 执行结果:
  4. 多窗口之间的切换工具封装:

python 复制代码
'''
思路:
1、获取所有窗口句柄
2、切换窗口
3、获取当前所在窗口title
4、判断title是否为需要的窗口
5、执行代码
'''


def switch_window(title):
    # 1、获取所有窗口句柄
    handles = driver.window_handles
    # 2、遍历句柄进行切换
    for handle in handles:
        driver.switch_to.window(handle)
        # 获取当前窗口title并且判断是否为自己需要的窗口
        if driver.title == title:
            # 操作代码
            return "已找到{}窗口,并且已切换成功".format(title)


# 1、获取浏览器(创建浏览器驱动对象)
driver = webdriver.Chrome()
# 2、输入URL,打开web页面
driver.get("http://hmshop-test.itheima.net/Home/Goods/goodsList/id/5.html")
driver.implicitly_wait(3)
title_B = "77"
driver.find_element(By.XPATH, "/html/body/div[4]/div/div[2]/div[2]/ul/li[1]/div/div[1]/a/img").click()
switch_window(title_B)
# 将商品加入购物车
driver.find_element(By.XPATH, "/html/body/div[3]/div/form/div/div[8]/div/a[2]").click()

3.6.元素定位不到怎么办

3.WebDriver常用方法

定位元素节点只是第一步, 定位之后还需要对这个元素进行操作, 比如单击按钮,或者在输入框输入文本 , 下面介绍 WebDriver 中的最常用方法:

python 复制代码
# 请求url
get(url)
# 模拟键盘输入文本
send_keys (value)
# 清除已经输入的文本
clear()
# 单击已经定位的元素
click()
# 用于提交表单,比如百度搜索框内输入关键字之后的"回车" 操作
submit()
#返回属性的属性值,返回元素的属性值,可以是id、name、type 或其他任意属性
get_attribute(name)
# 返回布尔值,检查元素是否用户可见,比如 display属性为hidden或者none
is_displayed()
python 复制代码
from selenium import webdriver

# 不自动关闭浏览器
option = webdriver.ChromeOptions()
option.add_experimental_option("detach", True)

# 由于版本迭代,新版的selenium已经不再使用find_element_by_id方法。
driver3 = webdriver.Chrome(option)
driver3.get("https://www.baidu.com")
#休眠
time.sleep(3)

# 模拟键盘,输出文本
driver3.find_element(By.ID, 'kw').send_keys("CSDN")
#休眠
time.sleep(3)

# 单击"百度"一下查找
driver3.find_element(By.ID, 'su').click()
#休眠
time.sleep(3)
# 退出/关闭浏览器
driver3.quit()

WebDriver 还有一些常用属性,如下所示:

python 复制代码
from selenium.webdriver.common.by import By
from selenium import webdriver

driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
#模拟键盘,输出文本
driver.find_element(By.ID,"kw").send_keys("CSDN")

# 在源码中查找指定的字符串
driver.page_source.find('字符串')
# 获取输入框的尺寸
size = driver.find_element(By.ID, 'kw').size
print(size)
#{'height': 38, 'width': 391}

4.Selenium事件处理

4.1.鼠标事件

Selenium WebDriver 将鼠标的操作封装在 ActionChains 类中,使用时需要引入 ActionChains 类

python 复制代码
from selenium.webdriver.common.action_chains import ActionChains

常用方法:

python 复制代码
ActionChains(driver)	构造 ActionChains 鼠标对象。
click()					单击
click_and_hold(on_element=None) 	单击鼠标左键,不松开
context_click()			右击
double_click()			双击
drag_and_drop()			拖动
move_to_element(above)	执行鼠标悬停操作
context_click()			用于模拟鼠标右键操作, 在调用时需要指定元素定位。
perform()				将所有鼠标操作提交执行。

如下示例

python 复制代码
import time
from selenium import webdriver
#导入 ActionChains 类
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.get("https://blog.csdn.net/qq877728715")

# 通过xpath表达式定位到要悬停的元素
above = driver.find_element(By.XPATH,'//div[@class="extension_official"]')

# 对定位到的元素执行鼠标悬停操作
ActionChains(driver).move_to_element(above).perform()
#单击悬停元素
driver.find_element(By.XPATH,'//div[@class="extension_official"]').click()

time.sleep(5)
driver.quit()

4.2.键盘事件

Selenium WebDriver 的 Keys 模块提供了操作键盘的方法,如复制、粘贴,使用时需要引入 Keys 类

python 复制代码
from selenium.webdriver.common.keys import Keys

常用方法:

python 复制代码
send_keys(Keys.BACK_SPACE)	删除键(BackSpace)
send_keys(Keys.SPACE)	空格键(Space)
send_keys(Keys.TAB)	制表键(Tab)
send_keys(Keys.ESCAPE)	回退键(Esc)
send_keys(Keys.ENTER)	回车键(Enter)
send_keys(Keys.CONTROL,'a')	全选(Ctrl+A)
send_keys(Keys.CONTROL,'c')	复制(Ctrl+C)
send_keys(Keys.CONTROL,'x')	剪切(Ctrl+X)
send_keys(Keys.CONTROL,'v')	粘贴(Ctrl+V)
send_keys(Keys.F1...Fn)	键盘 F1...Fn
keys.down(value,element=None)	按下键盘上的某个键
keys.up(value,element=None)	松开键盘上的某个键

如何调用方法

python 复制代码
from selenium.webdriver import Keys
from selenium.webdriver.common.by import By
# 初始化浏览器为谷歌浏览器
driver = webdriver.Chrome()

driver.find_element(By.ID,"element_id").send_keys("Python教程")#输入指定内容
driver.find_element(By.ID,"element_id").send_keys(Keys.SPACE)#空格键(Space)
driver.find_element(By.ID,"element_id").send_keys(Keys.TAB)#制表键(TAB)
driver.find_element(By.ID,"element_id").send_keys(Keys.ESCAPE)#回退键(ESCAPE)
driver.find_element(By.ID,"element_id").send_keys(Keys.ENTER)#回车键(ENTER)

# ctrl+x 剪切输入框内容
driver.find_element(By.ID,"element_id")send_keys(Keys.CONTROL, 'x')
# ctrl+v 粘贴内容到输入框
driver.find_element(By.ID,"element_id")send_keys(Keys.CONTROL, 'v')
# 使用回车键来代替单击操作click
driver.find_element(By.ID,"element_id")send_keys(Keys.ENTER)

示例如下:

python 复制代码
import time
from selenium import webdriver
#导入 ActionChains 类
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
# 引入 Keys 模块
from selenium.webdriver.common.keys import Keys
driver = webdriver.Chrome()
driver.get("https://blog.csdn.net/qq877728715")


#单击元素,弹出隐藏框
driver.find_element(By.XPATH,'//div[@class="m-search-input"]').click()
time.sleep(1)

# 输入框输入内容
driver.find_element(By.ID,"mSearchInput").send_keys("【Python】从入门到上头--- 多线程(9)1")
time.sleep(1)

# 删除多输入的"1"
driver.find_element(By.ID,"mSearchInput").send_keys(Keys.BACK_SPACE)
time.sleep(1)

#单击搜索按钮
driver.find_element(By.CLASS_NAME,"m-search-sure").click()
time.sleep(3)

driver.quit()

5.无界面浏览器

Chromedriver 每一次运行都要打开浏览器,并执行相应的输入、搜索等操作,这样会导致浏览器交互能力变差,浪费许多时间

  • Selenium 为了增强浏览器的交互能力,允许您使用无头浏览器模式,也就是无界面浏览器,它被广泛的应用于爬虫和自动化测试中。通过以下代码可以设置无头浏览器模式:

    python 复制代码
    import time
    from selenium import webdriver
    from selenium.webdriver.common.by import By
    
    options = webdriver.ChromeOptions()
    options.add_argument('--headless')  # 无界面浏览
    driver = webdriver.Chrome(options=options)
    
    driver.get("https://blog.csdn.net/qq877728715/article/details/127575556")
    
    # 单击元素,弹出隐藏框
    text = driver.find_element(By.XPATH, '//h1[@id="articleContentId"]').text
    print(text)
    
    time.sleep(3)
    # 关闭当前界面,只有一个窗口
    driver.close()
    # 关闭所有界面
    driver.quit()

设置无头界面之外,Selenium 还支持其他一些浏览器参数设置

python 复制代码
opption.add_argument('--window-size=600,600') #设置窗口大小
opption.add_argument('--incognito') #无痕模式
opption.add_argument('--disable-infobars') #去掉chrome正受到自动测试软件的控制的提示
opption.add_argument('user-agent="XXXX"') #添加请求头
opption.add_argument("--proxy-server=http://200.130.123.43:3456")#代理服务器访问
opption.add_experimental_option('excludeSwitches', ['enable-automation'])#开发者模式
opption.add_argument('blink-settings=imagesEnabled=false')  #禁止加载图片
opption.add_argument('lang=zh_CN.UTF-8') #设置默认编码为utf-8
opption.add_extension(create_proxyauth_extension(
           proxy_host='host',
           proxy_port='port',
           proxy_username="username",
           proxy_password="password"
       ))# 设置有账号密码的代理
opption.add_argument('--disable-gpu')  # 这个参数可以规避谷歌的部分bug
opption.add_argument('--disable-javascript')  # 禁用javascript
opption.add_argument('--hide-scrollbars')  # 隐藏滚动条

6.执行JS脚本

WebDriver 提供了 execute_script() 方法来执行 JavaScript 代码,比如控制浏览器的滚动条。

步骤如下

python 复制代码
1、方法:脚本名 = "window.scrollTo(x,y)"
	              x:左边距,控制左右滚动条
	              y:上边距,控制上下滚动条
	              单位:像素
	              边距数值:估算,不需要精确值
2、执行脚本:driver.execute_script(脚本名)


例如: 
#js->向下滚动
#document.body.scrollHeight:动态获取浏览器页面布局大小
js_down = "window.scrollTo(0,document.body.scrollHeight)"
driver.execute_script(js_down)

#js->向上滚动
js_top = "window.scrollTo(0,0)"
driver.execute_script(js_top)

实例如下

python 复制代码
import time

from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.get("https://blog.csdn.net/qq877728715/article/list/1")

# 最大化浏览器窗口
driver.maximize_window()
i = 1

while True:
    # 将页面滚动条拖到底部
    # 执行js语句,拉动进度条件
    driver.execute_script('window.scrollTo(0,document.body.scrollHeight)')
    # 给页面元素加载时预留时间
    time.sleep(2)

    # 判断是否是最一页(1说明没找到,不是最后一页,执行点击 "下一页" 操作)
    if driver.page_source.find('js-page-next js-page-action ui-pager ui-pager-disabled') == -1:
        i += 1
        driver.find_element(By.CLASS_NAME, 'js-page-next').click()
        # 预留元素加载时间
        time.sleep(1)
    else:
        print('数量', i)
        break

time.sleep(5)
# 关闭当前界面,只有一个窗口
driver.close()
# 关闭所有界面
driver.quit()

7.在源码中查找指定的字符串

python 复制代码
from selenium.webdriver import Keys
from selenium.webdriver.common.by import By
# 初始化浏览器为谷歌浏览器
chr = webdriver.Chrome()

chr.page_source.find('kw')
# # 获取输入框的尺寸
size = chr.find_element(By.ID,'kw').size
print(size)

六.Selenium项目实战

任务:抓取京东(https://www.jd.com/)商品名称、商品价格、评论数量,以及商铺名称。比如输入搜索"裹胸",则抓取如下数据:

1.实现自动搜索

实现自动输出、自动搜索是最基础的一步。首先定位输入框的的节点,其次定位搜索按钮节点,这与实现百度自动搜索思路一致,最关键就是要正确定位元素节点。

通过开发者调试工具检查相应的的位置,可得如下 Xpath 表达式

python 复制代码
输入框表达式:  //*[@id="key"]
搜索按钮表达式://*[@class='form']/button

代码如下所示:

python 复制代码
from selenium import webdriver
broswer=webdriver.Chrome()
broswer.get('https://www.jd.com/')
self.browser.find_element(By.XPATH, '//*[@id="key"]').send_keys('裹胸')
self.browser.find_element(By.XPATH, "//*[@class='form']/button").click()

2.滚动滑动条

实现了自动搜索后,接下来就是要抓取页面中的商品信息,而您会发现只有将滑动条滚动至底部,商品才会全部加载完毕。滚动滑轮操作的代码如下:

python 复制代码
# scrollTo(xpos,ypos)
# execute_script()执行js语句,拉动进度条件
#scrollHeight属性,表示可滚动内容的高度
self.browser.execute_script(
      'window.scrollTo(0,document.body.scrollHeight)'#拉动进度条至底部
)

之后在通过 Xpath 表达式匹配所有商品,并将它们放入一个大列表中,通过循环列表取出每个商品,最后提取出想要的信息。

python 复制代码
# 用 xpath 提取每页中所有商品,最终形成一个大列表
li_list = self.browser.find_elements(By.XPATH, '//*[@id="J_goodsList"]/ul/li')
print("li_list_size",len(li_list))
for li in li_list:
	 # 构建空字典
	item = {}
	item['name'] = li.find_element(By.XPATH, './/div[contains(@class,"p-name")]').text.strip()
	item['price'] = li.find_element(By.XPATH, './/div[@class="p-price"]/strong').text.strip()
	item['count'] = li.find_element(By.XPATH, './/div[@class="p-commit"]/strong').text.strip()
	item['shop'] = li.find_element(By.XPATH, './/div[@class="p-shop"]').text.strip()
	print(item)
	self.i += 1

3.实现翻页抓取

如何实现翻页抓取数据,并判断数据数据已经抓取完毕呢?这其实并不难想到,我们可以先跳至终止页(即最后一页)。此时最后一页的"下一页"处于不可用状态,其元素节点如下:

python 复制代码
终止页下一页class属性:<a class="pn-next disabled"><em>下一页</em><i> > </i></a>
其他页下一页class属性:<a class="pn-next" onclick="SEARCH.page(3, true)" ...><em>下一页</em><i> > </i></a>

如果页面源码中有上述代码存在,则证明此页是最后一页,若没有则不是。因此通过 if ...else 语句即可实现上述需求,如下所示:

纯文本复制

python 复制代码
#-1说明没找到,不是最后一页,执行点击 "下一页" 操作
if self.browser.page_source.find('pn-next disabled') == -1:
  self.browser.find_element(By.CLASS_NAME, 'pn-next').click()

4.完整程序代码

python 复制代码
# coding:utf8
from selenium import webdriver
import time
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
# 引入 Keys 模块
from selenium.webdriver.common.keys import Keys


class JdSpider(object):
    def __init__(self):
        self.url = 'http://www.jd.com/'
        self.options = webdriver.ChromeOptions()  # 无头模式
        self.options.add_argument('--headless')
        self.browser = webdriver.Chrome(options=self.options)  # 创建无界面参数的浏览器对象
        self.i = 0  # 计数,一共有多少件商品

        # 输入地址+输入商品+点击按钮,切记这里元素节点是京东首页的输入栏、搜索按钮
    def get_html(self):
        self.browser.get(self.url)
        self.browser.find_element(By.XPATH, '//*[@id="key"]').send_keys('裹胸')
        self.browser.find_element(By.XPATH, "//*[@class='form']/button").click()

        #滚动滑动条
        # 把滚动条拉倒最底部+提取商品信息
    def get_data(self):
        # 执行js语句,拉动进度条件
        self.browser.execute_script(
            'window.scrollTo(0,document.body.scrollHeight)'
        )
        # 给页面元素加载时预留时间
        time.sleep(2)
        # 用 xpath 提取每页中所有商品,最终形成一个大列表
        li_list = self.browser.find_elements(By.XPATH, '//*[@id="J_goodsList"]/ul/li')
        print("li_list_size",len(li_list))
        for li in li_list:
            # 构建空字典
            item = {}
            item['name'] = li.find_element(By.XPATH, './/div[contains(@class,"p-name")]').text.strip()
            item['price'] = li.find_element(By.XPATH, './/div[@class="p-price"]/strong').text.strip()
            item['count'] = li.find_element(By.XPATH, './/div[@class="p-commit"]/strong').text.strip()
            item['shop'] = li.find_element(By.XPATH, './/div[@class="p-shop"]').text.strip()
            print(item)
            self.i += 1

    def run(self):
        # 搜索出想要抓取商品的页面
        self.get_html()
        # 循环执行点击"下一页"操作
        while True:
            # 获取每一页要抓取的数据
            self.get_data()
            # 判断是否是最一页(1说明没找到,不是最后一页,执行点击 "下一页" 操作)
            if self.browser.page_source.find('pn-next disabled') == -1:
                self.browser.find_element(By.CLASS_NAME, 'pn-next').click()
                # 预留元素加载时间
                time.sleep(1)
            else:
                print('数量', self.i)
                break


if __name__ == '__main__':
    spider = JdSpider()
    spider.run()
    #Selenium 自动化爬虫让你无须关心网站的类型(静态或者动态),只需您按部就班的寻找元素节点,并依此点击,即可实现数据抓取。不过  Selenium 最大的缺点就是效率低,因此它只适合做小规模的数据采集工作。
相关推荐
databook7 小时前
Manim实现闪光轨迹特效
后端·python·动效
Juchecar8 小时前
解惑:NumPy 中 ndarray.ndim 到底是什么?
python
用户8356290780519 小时前
Python 删除 Excel 工作表中的空白行列
后端·python
Json_9 小时前
使用python-fastApi框架开发一个学校宿舍管理系统-前后端分离项目
后端·python·fastapi
数据智能老司机15 小时前
精通 Python 设计模式——分布式系统模式
python·设计模式·架构
数据智能老司机16 小时前
精通 Python 设计模式——并发与异步模式
python·设计模式·编程语言
数据智能老司机16 小时前
精通 Python 设计模式——测试模式
python·设计模式·架构
数据智能老司机16 小时前
精通 Python 设计模式——性能模式
python·设计模式·架构
c8i17 小时前
drf初步梳理
python·django
每日AI新事件17 小时前
python的异步函数
python