当前位置: 首页 > news >正文

基于Selenium模块实现无界面模式 执行JS脚本

此篇文章主要介绍如何使用 Selenium 模块实现 无界面模式 & 执行JS脚本(把滚动条拉到底部),并以具体的示例进行展示。

1、Selenium 设置无界面模式

创建浏览器对象之前,创建 options 功能对象 :options = webdriver.ChromeOptions()
添加无界面功能参数:options.add_argument("--headless")
构造浏览器对象,打开浏览器,并设置 options 参数:

browser = webdriver.Chrome(options=options)

from selenium import webdriver

options = webdriver.ChromeOptions()  # 创建浏览器对象之前,创建options功能对象
options.add_argument("--headless")  # 添加无界面功能参数
browser = webdriver.Chrome(options=options)  # 构造浏览器对象,打开浏览器

2、Selenium 执行JS脚本

创建浏览器对象:browser = webdriver.Chrome()
执行JS脚本:browser.execute_script()
最常用脚本 - 把滚动条拉到底部:browser.execute_script('window.scrollTo(0,document.body.scrollHeight)')
from selenium import webdriver

browser = webdriver.Chrome() # 创建浏览器对象
browser.execute_script(
    'window.scrollTo(0,document.body.scrollHeight)'
) # 把滚动条拉到最底部

3、Selenium 设置无界面模式 & 执行JS脚本 案例

3.1 需求分析
基于 Selenium + Chrome 抓取 `http://www.jd.com/` 下 “python书籍” 的信息

3.2 爬虫思路
打开浏览器输入主页地址:https://www.jd.com/
使用 Selenium 的 Xpath 找到 信息输入框 和 点击搜索 节点:'//*[@id="key"]' & '//*[@id="search"]/div/div[2]/button'

输入 “python书籍” 并点击 点击搜索按钮;
使用 Selenium 的 Xpath 找到 书籍信息 节点对象列表: '//*[@id="J_goodsList"]/ul/li'; 
依次遍历每个元素,并依次提取每本书籍信息;
爬取完一页信息后,需要判断是否是最后一页

可以看到:
最后一页的节点信息为:pn-next disabled
非最后一页的节点信息为:pn-next
如果不是最后一页,点击下一页继续进行爬取:'//*[@id="J_bottomPage"]/span[1]/a[9]'

3.3 程序实现

初始化函数
    def __init__(self):
        # 设置为无界面
        self.options = webdriver.ChromeOptions()  # 创建浏览器对象之前,创建options功能对象
        self.options.add_argument('--headless')  # 添加无界面功能参数
        self.driver = webdriver.Chrome(options=self.options)  # 构造浏览器对象,打开浏览器
        self.driver.get(url="http://www.jd.com/")  # 进入主页
        # 搜索框发送:python书籍,点击搜索按钮
        self.inputJD = self.driver.find_element(By.XPATH, '//*[@id="key"]')  # 搜索框xpath://*[@id="key"]
        self.inputJD.send_keys("python书籍")
        self.driver.find_element(By.XPATH,
                                 '//*[@id="search"]/div/div[2]/button').click()  # 搜索按钮xpath://*[@id="search"]/div/div[2]/button 并点击
        time.sleep(1)  # 要给页面元素加载预留时间

提取数据函数

    def parse_html(self):
        """
        function:  具体提取数据方法
              in:  None
             out:  None
          return:  None
          others:  Data Extraction Func
        """
        self.driver.execute_script(
            'window.scrollTo(0,document.body.scrollHeight)'
        )  # 先把滚动条拉到最底部,等待所有商品加载完成再进行数据爬取
        time.sleep(3)  # 给页面元素加载预留时间
        # 具体提取数据
        li_list = self.driver.find_elements(By.XPATH,
                                            '//*[@id="J_goodsList"]/ul/li')  # 基准xpath://*[@id="J_goodsList"]/ul/li 每一个商品对应一个li节点
        item = {}  # 定义一个空字典
        for li in li_list:
            item["名称"] = li.find_element(By.XPATH, './/div[@class="p-name"]/a/em').text.strip()
            item["价格"] = li.find_element(By.XPATH, './/div[@class="p-price"]/strong').text.strip()
            item["评价"] = li.find_element(By.XPATH, './/div[@class="p-commit"]/strong').text.strip()
            item["商家"] = li.find_element(By.XPATH, './/div[@class="p-shopnum"]').text.strip()
            print(item)  # 打印

程序入口函数

    def run(self):
        """
        function:  程序入口函数
              in:  None
             out:  None
          return:  None
          others:  Program Entry Func
        """
        while True:
            self.parse_html()
            # 不是最后一页:pn-next
            # 最后一页:pn-next disabled
            if self.driver.page_source.find("pn-next disabled") == -1:  # 没有找到 pn-next disabled,说明不是最后一页
                self.driver.find_element(By.XPATH, '//*[@id="J_bottomPage"]/span[1]/a[9]').click()
                time.sleep(1)
            else:
                self.driver.quit()
                break


3.4 完整代码

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

class JDSpider:
    def __init__(self):
        # 设置为无界面
        self.options = webdriver.ChromeOptions()  # 创建浏览器对象之前,创建options功能对象
        self.options.add_argument('--headless')  # 添加无界面功能参数
        self.driver = webdriver.Chrome(options=self.options)  # 构造浏览器对象,打开浏览器

        self.driver.get(url="http://www.jd.com/")  # 进入主页
        # 搜索框发送:python书籍,点击搜索按钮
        self.inputJD = self.driver.find_element(By.XPATH, '//*[@id="key"]')  # 搜索框xpath://*[@id="key"]
        self.inputJD.send_keys("python书籍")
        self.driver.find_element(By.XPATH,
                                 '//*[@id="search"]/div/div[2]/button').click()  # 搜索按钮xpath://*[@id="search"]/div/div[2]/button 并点击
        time.sleep(1)  # 要给页面元素加载预留时间

    def parse_html(self):
        """
        function:  具体提取数据方法
              in:  None
             out:  None
          return:  None
          others:  Data Extraction Func
        """
        self.driver.execute_script(
            'window.scrollTo(0,document.body.scrollHeight)'
        )  # 先把滚动条拉到最底部,等待所有商品加载完成再进行数据爬取
        time.sleep(3)  # 给页面元素加载预留时间
        # 具体提取数据
        li_list = self.driver.find_elements(By.XPATH,
                                            '//*[@id="J_goodsList"]/ul/li')  # 基准xpath://*[@id="J_goodsList"]/ul/li 每一个商品对应一个li节点
        item = {}  # 定义一个空字典
        for li in li_list:
            item["名称"] = li.find_element(By.XPATH, './/div[@class="p-name"]/a/em').text.strip()
            item["价格"] = li.find_element(By.XPATH, './/div[@class="p-price"]/strong').text.strip()
            item["评价"] = li.find_element(By.XPATH, './/div[@class="p-commit"]/strong').text.strip()
            item["商家"] = li.find_element(By.XPATH, './/div[@class="p-shopnum"]').text.strip()
            print(item)  # 打印

    def run(self):
        """
        function:  程序入口函数
              in:  None
             out:  None
          return:  None
          others:  Program Entry Func
        """
        while True:
            self.parse_html()
            # 不是最后一页:pn-next
            # 最后一页:pn-next disabled
            if self.driver.page_source.find("pn-next disabled") == -1:  # 没有找到 pn-next disabled,说明不是最后一页
                self.driver.find_element(By.XPATH, '//*[@id="J_bottomPage"]/span[1]/a[9]').click()
                time.sleep(1)
            else:
                self.driver.quit()
                break

if __name__ == '__main__':
    spider = JDSpider()
    spider.run()

3.5 实现效果

 

相关文章:

基于Selenium模块实现无界面模式 执行JS脚本

此篇文章主要介绍如何使用 Selenium 模块实现 无界面模式 & 执行JS脚本(把滚动条拉到底部),并以具体的示例进行展示。 1、Selenium 设置无界面模式 创建浏览器对象之前,创建 options 功能对象 :options webdriver.ChromeOptions() 添加…...

【LangChain学习】基于PDF文档构建问答知识库(二)创建项目

这里我们使用到 fastapi 作为项目的web框架,它是一个快速(高性能)的 web 框架,上手简单。 一.创建 FastAPI 项目 我们在IDE中,左侧选择 FastAPI ,右侧选择创建一个新的虚拟环境。 创建成功,会有…...

【Kubernetes】Kubernetes之kubectl详解

kubectl 一、陈述式资源管理1. 陈述式资源管理方法2. 基本信息查看3. 项目周期管理3.1 创建 kubectl create 命令3.2 发布 kubectl expose命令3.3 更新 kubectl set3.4 回滚 kubectl rollout3.5 删除 kubectl delete 4. kubectl 的发布策略4.1 蓝绿发布4.2 红黑发布4.3 灰度发布…...

【torch.nn.PixelShuffle】和 【torch.nn.UnpixelShuffle】

文章目录 torch.nn.PixelShuffle直观解释官方文档 torch.nn.PixelUnshuffle直观解释官方文档 torch.nn.PixelShuffle 直观解释 PixelShuffle是一种上采样方法,它将形状为 ( ∗ , C r 2 , H , W ) (∗, C\times r^2, H, W) (∗,Cr2,H,W)的张量重新排列转换为形状为…...

Rocky9 KVM网桥的配置

KVM的默认网络模式为NAT,借助宿主机模式上网,现在我们来改成桥接模式,这样外界就可以直接和宿主机里的虚拟机通讯了。 Bridge方式即虚拟网桥的网络连接方式,是客户机和子网里面的机器能够互相通信。可以使虚拟机成为网络中具有独立IP的主机。 桥接网络(也叫物理设备共享…...

爬虫013_函数的定义_调用_参数_返回值_局部变量_全局变量---python工作笔记032

然后再来看函数,可以避免重复代码 可以看到定义函数以及调用函数...

将.doc文档的默认打开方式从WPS修改为word office打开方式的具体方法(以win 10 操作系统为例)

将.doc文档的默认打开方式从WPS修改为word office打开方式的具体方法(以win 10 操作系统为例) 随着近几年WPS软件的不断完善和丰富,在某些方面取得了具有特色的优势。在平时编辑.doc文档时候也常常用到wps软件,不过WPS文献也存在…...

如何搭建个人的GPT网页服务

写在前面 在创建个人的 GPT网页之前,我登录了 Git 并尝试了一些开源项目,但是没有找到满足我个性化需求的设计。虽然许多收费的 GPT网页提供了一些免费额度,足够我使用,但是公司的安全策略会屏蔽这些网页。因此,我决定…...

[QCM6125][Android13] 默认关闭SELinux权限

文章目录 开发平台基本信息问题描述解决方法 开发平台基本信息 芯片: QCM6125 版本: Android 13 kernel: msm-4.14 问题描述 正常智能硬件设备源码开发,到手的第一件事就是默认关闭SELinux权限,这样能够更加方便于调试功能。 解决方法 --- a/QSSI.1…...

【jvm】jvm发展历程

目录 一、Sun Classic VM二、Exact VM三、HotSpot VM四、JRockit五、J9六、KVM、CDC、CLDC七、Azul VM八、Liquid VM九、Apache Harmony十、Microsoft JVM十一、Taobao JVM十二、Dalvik VM 一、Sun Classic VM 1.1996年java1.0版本,sun公司发布了sun classic vm虚拟…...

Dubbo3.0 Demo

将SpringBoot工程集成Dubbo 1.创建父工程 2.创建子工程consumer&#xff0c;provider 3.初始化工程 4.引入依赖 在provider和consumer中引入dubbo依赖 <dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-spring-boot-starter</a…...

源码分析——ConcurrentHashMap源码+底层数据结构分析

文章目录 1. ConcurrentHashMap 1.71. 存储结构2. 初始化3. put4. 扩容 rehash5. get 2. ConcurrentHashMap 1.81. 存储结构2. 初始化 initTable3. put4. get 3. 总结 1. ConcurrentHashMap 1.7 1. 存储结构 Java 7 中 ConcurrentHashMap 的存储结构如上图&#xff0c;Concurr…...

R语言中的函数25:paste,paste0

文章目录 介绍paste0()实例 paste()实例 介绍 paste0()和paste()函数都可以实现对字符串的连接&#xff0c;paste0是paste的简化版。 paste0() paste (..., sep " ", collapse NULL, recycle0 FALSE)… one or more R objects, to be converted to character …...

(八)穿越多媒体奇境:探索Streamlit的图像、音频与视频魔法

文章目录 1 前言2 st.image&#xff1a;嵌入图像内容2.1 图像展示与描述2.2 调整图像尺寸2.3 使用本地文件或URL 3 st.audio&#xff1a;嵌入音频内容3.1 播放音频文件3.2 生成音频数据播放 4 st.video&#xff1a;嵌入视频内容4.1 播放视频文件4.2 嵌入在线视频 5 结语&#x…...

CAD练习——绘制房子平面图

首先还是需要设置图层、标注、文字等 XL&#xff1a;构造线 用构造线勾勒大致的轮廓&#xff1a; 使用多线命令&#xff1a;ML 绘制墙壁 可以看到有很多交叉点的位置 用多线编辑工具将交叉点处理 有一部分处理不了的&#xff0c;先讲多线分解&#xff0c;然后用修剪打理&…...

spring 面试题

一、Spring面试题 专题部分 1.1、什么是spring? Spring是一个轻量级Java开发框架&#xff0c;最早有Rod Johnson创建&#xff0c;目的是为了解决企业级应用开发的业务逻辑层和其他各层的耦合问题。它是一个分层的JavaSE/JavaEE full-stack&#xff08;一站式&#xff09;轻量…...

Springboot项目集成Durid数据源和P6Spy以及dbType not support问题

项目开发阶段&#xff0c;mybatis的SQL打印有占位符&#xff0c;调试起来还是有点麻烦&#xff0c;随想整合P6Spy打印可以直接执行的SQL&#xff0c;方便调试&#xff0c;用的Durid连接池。 Springboot项目集成Durid <dependency><groupId>com.alibaba</group…...

安卓如何卸载应用

卸载系统应用 首先需要打开手机的开发者选项&#xff0c;启动usb调试。 第二步需要在电脑上安装adb命令&#xff0c;喜欢的话还可以将它加入系统path。如果不知道怎么安装&#xff0c;可以从这里下载免安装版本。 第三步将手机与电脑用数据线连接&#xff0c;注意是数据线&a…...

【云原生|Kubernetes】14-DaemonSet资源控制器详解

【云原生|Kubernetes】14-DaemonSet资源控制器详解 文章目录 【云原生|Kubernetes】14-DaemonSet资源控制器详解简介典型用法DaemonSet语法规则Pod模板Pod 选择算符在选定的节点上运行 Pod DaemonSet的 Pods 是如何被调度的污点和容忍度DaemonSet更新和回滚DaemonSet更新策略执…...

基于 Guava Retry 在Spring封装一个重试功能

pom依赖 <dependency><groupId>com.github.rholder</groupId><artifactId>guava-retrying</artifactId><version>2.0.0</version> </dependency> <dependency><groupId>org.springframework.boot</groupId>…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

SciencePlots——绘制论文中的图片

文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了&#xff1a;一行…...

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中&#xff0c;我们可能会遇到一些流式数据处理的场景&#xff0c;比如接收来自上游接口的 Server-Sent Events&#xff08;SSE&#xff09; 或 流式 JSON 内容&#xff0c;并将其原样中转给前端页面或客户端。这种情况下&#xff0c;传统的 RestTemplate 缓存机制会…...

Debian系统简介

目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版&#xff…...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件

今天呢&#xff0c;博主的学习进度也是步入了Java Mybatis 框架&#xff0c;目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学&#xff0c;希望能对大家有所帮助&#xff0c;也特别欢迎大家指点不足之处&#xff0c;小生很乐意接受正确的建议&…...

DBAPI如何优雅的获取单条数据

API如何优雅的获取单条数据 案例一 对于查询类API&#xff0c;查询的是单条数据&#xff0c;比如根据主键ID查询用户信息&#xff0c;sql如下&#xff1a; select id, name, age from user where id #{id}API默认返回的数据格式是多条的&#xff0c;如下&#xff1a; {&qu…...

Map相关知识

数据结构 二叉树 二叉树&#xff0c;顾名思义&#xff0c;每个节点最多有两个“叉”&#xff0c;也就是两个子节点&#xff0c;分别是左子 节点和右子节点。不过&#xff0c;二叉树并不要求每个节点都有两个子节点&#xff0c;有的节点只 有左子节点&#xff0c;有的节点只有…...

dify打造数据可视化图表

一、概述 在日常工作和学习中&#xff0c;我们经常需要和数据打交道。无论是分析报告、项目展示&#xff0c;还是简单的数据洞察&#xff0c;一个清晰直观的图表&#xff0c;往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server&#xff0c;由蚂蚁集团 AntV 团队…...

深度学习习题2

1.如果增加神经网络的宽度&#xff0c;精确度会增加到一个特定阈值后&#xff0c;便开始降低。造成这一现象的可能原因是什么&#xff1f; A、即使增加卷积核的数量&#xff0c;只有少部分的核会被用作预测 B、当卷积核数量增加时&#xff0c;神经网络的预测能力会降低 C、当卷…...

LeetCode - 199. 二叉树的右视图

题目 199. 二叉树的右视图 - 力扣&#xff08;LeetCode&#xff09; 思路 右视图是指从树的右侧看&#xff0c;对于每一层&#xff0c;只能看到该层最右边的节点。实现思路是&#xff1a; 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...