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

文章目录

  • 一.介绍
  • 二.下载安装selenium
  • 三.安装浏览器驱动
  • 四.QuickStart—自动访问百度
  • 五.Selenium基本用法
    • 1.定位节点
      • 1.1.单个元素定位
      • 1.2.多个元素定位
    • 2.控制浏览器
      • 2.1.设置浏览器窗口大小、位置
      • 2.2.浏览器前进、刷新、后退、关闭
      • 3.3.等待
      • 3.4.Frame
      • 3.5.多窗口
      • 3.6.元素定位不到怎么办
    • 3.WebDriver常用方法
    • 4.Selenium事件处理
      • 4.1.鼠标事件
      • 4.2.键盘事件
    • 5.无界面浏览器
    • 6.执行JS脚本
    • 7.在源码中查找指定的字符串
  • 六.Selenium项目实战
    • 1.实现自动搜索
    • 2.滚动滑动条
    • 3.实现翻页抓取
    • 4.完整程序代码

一.介绍

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 用户执行以下命令即可:

pip install Selenium

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

python -m pip install selenium

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

三.安装浏览器驱动

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

  • 常见浏览器驱动下载地址如下

    • 谷歌浏览器 chromedrive:http://chromedriver.storage.googleapis.com/index.html
    • 火狐浏览器 geckodriver:https://github.com/mozilla/geckodriver/releases
    • IE 浏览器 IEDriver:http://selenium-release.storage.googleapis.com/index.html
    • chromedriver高于114版本的版本如115、116、117、118等,如何下载对应版本
      • python编写的在windows下自动更新下载对应版本chromedriver脚本
  • 需要注意的是:各种浏览器的驱动安装方式基本一致。但安装Chrome、Firefox 驱动时,需要下载与浏览器版本相匹配的驱动程序,否则不能驱动浏览器。而 IE 较为特殊,您需要下载与 Selenium 版本相匹配的驱动文件,如下所示:

在这里插入图片描述

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

  • 查看 Python 安装路径:

    where python
    

    在这里插入图片描述

    环境变量配置如下
    在这里插入图片描述
    完成上述操作后,命令行启动驱动程序

    chromedriver
    

    在这里插入图片描述

    • 开启成功后,驱动程序会在后台运行

四.QuickStart—自动访问百度

# 导入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 种定位单个节点的方法如下:

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>
<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 输出框。如下所示:

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 标签内的文本内容定位节点,如下所示:

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

1.2.多个元素定位

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

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.设置浏览器窗口大小、位置

from selenium import webdriverdriver1 = 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.浏览器前进、刷新、后退、关闭

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(秒)

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

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

  • 说明:针对单个元素生效,可以修改查找频率和超时时间
  • 特点:查找并返回元素。
  • 用法
    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
      • 通过元素切换:
      element = driver.find_element(By.XPATH,'iframe')
      driver.switch_to.frame(element)
      
  • 切换回默认页面

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

代码示例

#获取注册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. 如何切换?

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

    # 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. 多窗口之间的切换工具封装:

'''
思路:
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 中的最常用方法:

# 请求url
get(url)
# 模拟键盘输入文本
send_keys (value)
# 清除已经输入的文本
clear()
# 单击已经定位的元素
click()
# 用于提交表单,比如百度搜索框内输入关键字之后的“回车” 操作
submit()
#返回属性的属性值,返回元素的属性值,可以是id、name、type 或其他任意属性
get_attribute(name)
# 返回布尔值,检查元素是否用户可见,比如 display属性为hidden或者none
is_displayed()
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 还有一些常用属性,如下所示:

from selenium.webdriver.common.by import By
from selenium import webdriverdriver = 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 类

from selenium.webdriver.common.action_chains import ActionChains

常用方法:

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

如下示例

import time
from selenium import webdriver
#导入 ActionChains 类
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import Bydriver = 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 类

from selenium.webdriver.common.keys import Keys

常用方法:

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)	松开键盘上的某个键

如何调用方法

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)

示例如下:

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

    import time
    from selenium import webdriver
    from selenium.webdriver.common.by import Byoptions = 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 还支持其他一些浏览器参数设置

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 代码,比如控制浏览器的滚动条。

步骤如下

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)

实例如下

import timefrom selenium import webdriver
from selenium.webdriver.common.by import Bydriver = webdriver.Chrome()
driver.get("https://blog.csdn.net/qq877728715/article/list/1")# 最大化浏览器窗口
driver.maximize_window()
i = 1while 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 += 1driver.find_element(By.CLASS_NAME, 'js-page-next').click()# 预留元素加载时间time.sleep(1)else:print('数量', i)breaktime.sleep(5)
# 关闭当前界面,只有一个窗口
driver.close()
# 关闭所有界面
driver.quit()

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

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 表达式

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

代码如下所示:

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.滚动滑动条

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

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

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

# 用 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.实现翻页抓取

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

终止页下一页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 语句即可实现上述需求,如下所示:
纯文本复制

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

4.完整程序代码

# 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 Keysclass 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 += 1def 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)breakif __name__ == '__main__':spider = JdSpider()spider.run()#Selenium 自动化爬虫让你无须关心网站的类型(静态或者动态),只需您按部就班的寻找元素节点,并依此点击,即可实现数据抓取。不过  Selenium 最大的缺点就是效率低,因此它只适合做小规模的数据采集工作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/154124.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

为Yolov7环境安装Cuba匹配的Pytorch

1. 查看Cuba版本 方法一 nvidia-smi 找到CUDA Version 方法二 Nvidia Control Panel > 系统信息 > 组件 > 2. 安装Cuba匹配版本的PyTorch https://pytorch.org/get-started/locally/这里使用conda安装 conda install pytorch torchvision torchaudio pytorch-cu…

Oracle笔记-对ROWNUM的一次理解(简单分页)

此博文记录时间&#xff1a;2023-05-05&#xff0c;发到互联网上是2023-10-09 这个在分页里面用得比较多&#xff0c;在MySQL中&#xff0c;通常使用limit去操作&#xff0c;而去感觉比较简单&#xff0c;Oracle中无此关键字。 通过查阅资料后&#xff0c;要实现分页需要用到…

Lab 1: Unix utilities汇总

这个实验主要学习了常用的一些系统调用。 Lab 1: Unix utilities Boot xv6 (easy) git克隆&#xff0c;切换分支&#xff0c;qemu。根据要求进行操作即可。 $ git clone git://g.csail.mit.edu/xv6-labs-2020 $ cd xv6-labs-2020 $ git checkout util $ make qemusleep (ea…

idea将jar包deploy到本地仓库

1、pom.xml文件引入配置&#xff0c;如下参考&#xff1a; <distributionManagement><snapshotRepository><id>maven-snapshots</id><url>http://nexus1.coralglobal.cn/repository/maven-snapshots/</url></snapshotRepository><…

唐老师讲电赛

dc-dc电源布局要点

【C++】:日期类实现

朋友们、伙计们&#xff0c;我们又见面了&#xff0c;本期来给大家解读一下有关Linux的基础知识点&#xff0c;如果看完之后对你有一定的启发&#xff0c;那么请留下你的三连&#xff0c;祝大家心想事成&#xff01; C 语 言 专 栏&#xff1a;C语言&#xff1a;从入门到精通 数…

cesium图标漂移分析与解决

漂移现象如下 什么是图标漂移&#xff1f; 随着视野改变&#xff0c;图标相对于地面发生了相对位置的变化 让人感觉到图标有飘忽不定的感觉 原因分析 图标是静止的&#xff0c;它的位置在世界坐标系中是绝对的、静止的。 漂移大部分的原因是&#xff1a; 透视关系发生了错…

增强LLM:使用搜索引擎缓解大模型幻觉问题

论文题目&#xff1a;FRESHLLMS:REFRESHING LARGE LANGUAGE MODELS WITH SEARCH ENGINE AUGMENTATION 论文地址&#xff1a;https://arxiv.org/pdf/2310.03214.pdf 论文由Google、University of Massachusetts Amherst、OpenAI联合发布。 大部分大语言模型只会训练一次&#…

gin 框架的 JSON Render

gin 框架的 JSON Render gin 框架默认提供了很多的渲染器&#xff0c;开箱即用&#xff0c;非常方便&#xff0c;特别是开发 Restful 接口。不过它提供了好多种不同的 JSON Render&#xff0c;那么它们的区别是什么呢&#xff1f; // JSON contains the given interface obje…

三、WebGPU Uniforms

三、WebGPU Uniforms Uniform有点像着色器的全局变量。你可以在执行着色器之前设置它们的值&#xff0c;着色器的每次迭代都会有这些值。你可以在下一次请求GPU执行着色器时将它们设置为其他值。我们将再次从第一篇文章中的三角形示例开始&#xff0c;并对其进行修改以使用一些…

【初识Jmeter】【接口自动化】

jmeter的使用笔记1 Jmeter介绍与下载安装介绍安装配置配置与扩展组件 jmeter的使用基本功能元素登陆请求与提取cookie其他请求接口关联Cookie-响应成功聚合报告查看 Jmeter介绍与下载安装 介绍 jmeter是apache公司基于java开发的一款开源压力测试工具&#xff0c;体积小&…

nio 文件传输

transferto方法一次只能传输2个g的数据 文件大于2个g时

C# Windows 窗体控件中的边距和填充

可以将 Margin 属性、Left、Top、Right、Bottom 的每个方面设置为不同的值&#xff0c;也可以使用 All 属性将它们全部设置为相同的值。 在代码中设置Margin&#xff0c;元素的左边设置为5个单位、上边设置为10个单位、右边设置为15个单位和下边设置为20个单位。 TextBox myT…

Java学数据结构(4)——PriorityQueue(优先队列) 二叉堆(binary heap)

前言 数据结构与算法作为计算机科学的基础&#xff0c;是一个重点和难点&#xff0c;在实际编程中似乎看不它们的身影&#xff0c;但是它们有随处不在&#xff0c;如影随形。 本系列博客是《数据结构与算法分析—Java语言描述》的读书笔记&#xff0c;合集文章列表如下&#…

数据安全防护:云访问安全代理(CASB)

云访问安全代理&#xff08;Cloud Access Security Broker&#xff0c;CASB&#xff09;&#xff0c;是一款面向应用的数据防护服务&#xff0c;基于免应用开发改造的配置方式&#xff0c;提供数据加密、数据脱敏功能。数据加密支持国密算法&#xff0c;提供面向服务侧的字段级…

Springboot+vue的企业OA管理系统(有报告),Javaee项目,springboot vue前后端分离项目。

演示视频&#xff1a; Springbootvue的企业OA管理系统&#xff08;有报告&#xff09;&#xff0c;Javaee项目&#xff0c;springboot vue前后端分离项目。 项目介绍&#xff1a; 本文设计了一个基于Springbootvue的前后端分离的企业OA管理系统&#xff0c;采用M&#xff08;m…

【电商API接口的应用:电商数据分析入门】初识Web API(一)

如何使用Web应用变成接口(API)自动请求网站到特定信息而不是整个网站&#xff0c;再对这些信息进行可视化。由于这样编写到程序始终使用最新到数据来生成可视化&#xff0c;因此即便数据瞬息万变&#xff0c;它呈现到信息也都是最新的。 使用Web API Web API是网站的一部分&am…

揭秘 Go 中的 new() 和 make() 函数

Go&#xff08;或 Golang&#xff09;是一种现代、静态类型、编译型的编程语言&#xff0c;专为构建可扩展、并发和高效的软件而设计。它提供了各种内置的函数和特性&#xff0c;帮助开发人员编写简洁高效的代码。其中包括 new() 和 make() 函数&#xff0c;这两个函数乍看起来…

有哪些值得推荐的Java 练手项目?

大家好&#xff0c;我是 jonssonyan 我是一名 Java 后端程序员&#xff0c;偶尔也会写一写前端&#xff0c;主要的技术栈是 JavaSpringBootMySQLRedisVue.js&#xff0c;基于我学过的技术认真的对每个分享的项目进行鉴别&#xff0c;今天就和大家分享我曾经用来学习的开源项目…

【置顶】关于博客的一些公告

所谓 万事开头难&#xff0c;最开始的两个专栏 《微机》 和 《骨骼动作识别》 定价 29.9 &#xff0c;因为&#xff1a; 刚开始确实比较困难&#xff0c;要把自己学的知识彻底搞懂讲给别人&#xff0c;还要 码字排版&#xff0c;从 Markdown 语法开始学起&#xff08;这都是 花…