Python使用Selenium Webdriver爬取网页所有内容

news2024/11/25 2:50:05

Python使用Selenium Webdriver爬取网页所有内容

  • 一、为什么我抓不到网页的全部html内容
  • 二、Selenium的基本使用
  • 三、使用Selenium抓取全部HTML

一、为什么我抓不到网页的全部html内容

有时候,我们在用urllib或者requests库抓取页面时,得到的html源代码和浏览器中看到的不一样。这将是我们面临的一个非常常见的问题。现在网页越来越多地采用Ajax、前端模块化工具来构建,整个网页可能都是由JavaScript渲染出来的,也就是说原始的HTML代码可能就是一个空壳,例如:

<!DOCTYPE html>
<html>
    
    <head>
        <meta charset="UTF-8">
        <title>
            this is a demo
        </title>
    </head>
    
    <body>
        <div id="container">
        </div>
    </body>
    <script src="app.js">
    </script>

</html>

body节点里面只有一个id为container的节点,但是需要注意在body节点后引入了app.js, 它便负责整个网站的渲染。

在浏览器中打开这个页面时,首先会加载这个HTML内容,接着浏览器会发现其中引入了一个app.js文件,然后便会接着去请求这个文件,获取到该文件后,便会执行其中的JavaScript代码,而JavaScript则会改变HTML中的节点,向其中添加内容,最后得到完整的页面。

但是在用urllib或者requests等库请求当前页面时,我们得到的只是这个HTML代码,它不会帮助我们去继续加载这个JavaScript文件,这样也就看不到浏览器中的内容了。

而且,JavaScript动态渲染的页面可不止Ajax这一种,还有其他各种原因会导致我们得到的源代码和浏览器中看到的不一样。

对于抓不到全部html内容的情况,我们能采取什么应对措施呢,本文介绍一种可行的方法,就是通过Selenium webdriver来模拟浏览器运行的方式,这样就可以做到在浏览器中看到是什么样,抓取的源码就是什么样,也就是可见即可爬。这样,我们就不用再去管网页内部的JavaScript用了什么算法渲染页面,也不用管网页后台的Ajax接口到底有哪些参数。所有的这些,都交给Selenium webdriver来帮我们完成。

二、Selenium的基本使用

Selenium是一个自动化测试工具,利用它可以驱动浏览器执行特定的动作,如点击、下拉等操作,同时还可以获取浏览器当前呈现的页面的源代码,做到可见即可爬。对于一些JavaScript动态渲染的页面来说,此种抓取方式非常有效。

Selenium webdriver的安装和基本使用方法,可以参考另一篇文章。
Python使用Selenium WebDriver的入门介绍及安装教程

Selenium的官方网站:
Selenium WebDriver

一些基本的用法,此处不再赘述。

三、使用Selenium抓取全部HTML

先看使用requests库直接提取到的代码,可以发现并不是完整的:

20221214220011

使用Selenium拿到的html代码,可以看到已经可以通过src属性提取到图片的url:

20221214220124

示例代码如下,详细的解读可以参考每一步的注释:

from selenium.webdriver import Firefox, FirefoxOptions
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

class ContentPageParser():
    def __init__(self, content_page_url) -> None:
        self.content_url = content_page_url # 抓取content_page_url页面上全部的图片url
        self.img_src = []                   # 保存当前页面上所有的图片url
    
    def visit_content_page_with_firefox(self):
        option = FirefoxOptions()
        # 设置浏览器为无头模式,使用过程中不会弹出浏览器页面
        option.headless = True
        self.driver = Firefox(options=option)
        try:
            # 打开待抓取的url页面
            self.driver.get(self.content_url)
            # 设置灵活等待,最长等待10s,轮询间隔为1s
            wait = WebDriverWait(self.driver, timeout=10, poll_frequency=1)
            # 使用css选择器进行元素定位,直到元素可见为止
            wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, 'img[class="showimg"]')))
            # 使用css选择器查找所有元素
            imgs = self.driver.find_elements(By.CSS_SELECTOR, 'img[class="showimg"]')
            # 提取所有图片的url
            for img in imgs:
                self.img_src.append(img.get_attribute('src'))
        except Exception as e:
            print(repr(e))
        finally:
            # 关闭webdriver
            self.driver.close() 
    
    def get_img_src(self):
        return self.img_src
    
if __name__ == '__main__':
    content_parser = ContentPageParser('https://xxx/content_48495.html')
    content_parser.visit_content_page_with_firefox()
    img = content_parser.get_img_src()
    print(img)

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

4年测试在岗,薪资却被春招来的年轻人超过了,其实你一直在假装努力~

最近和一位同行朋友聊天&#xff0c;一开始大家也没有谈工作&#xff0c;毕竟是出来聚聚&#xff0c;放松一下&#xff0c;吃饭的时候&#xff0c;喝了点小酒&#xff0c;酒过三巡&#xff0c;这个朋友开始诉苦水&#xff0c;大概意思嘞&#xff0c;我给大家概况一下&#xff0…

STM32F4的关键要点分析

1. 从以上截图信息可以看出&#xff1a; 1.当外设数据宽度和内存数据宽度不相等时&#xff0c;要传输的数据项数目的数据宽度由外设数据宽度确定&#xff1b; 2.在直接模式下&#xff08;不使用FIFO&#xff09;&#xff0c;不能进行数据的封装/解封&#xff0c;且源数据宽度和…

Docker-Docker安装nginx

目录 一&#xff0c;容器之间的相互通信 ping 1.1 两个容器在同一网段 1.2 两个容器在不同网段 二&#xff0c;安装Nginx 2.1 nginx是什么 安装步骤 2.4 部署前端项目 上传项目 步骤 一&#xff0c;容器之间的相互通信 ping 1.1 两个容器在同一网段 1.2 两个容器在不同网段…

旋转机械 | 基于ANSYS WB平台的滑动轴承分析工具(一)

导读&#xff1a;本文主要针对Tribo-X inside ANSYS的功能及各方向应用实例进行介绍&#xff0c;限于篇幅关系会分五篇进行介绍&#xff0c;第一篇主要结合软件的需求、理论、功能及应用方向进行介绍&#xff0c;第二篇至第五篇将结合具体应用方向的示例进行介绍。本篇为第一篇…

软件测试工程师的简历项目经验该怎么写?

想要找一份高薪的软件测试工作&#xff0c;简历项目必不可少&#xff08;即使是应届生&#xff0c;你也要写上实习项目&#xff09;。所以很多自学的朋友找工作时会碰到一个令人颇感绝望的拦路虎&#xff1a;个人并没有实际的项目工作经验怎么办&#xff1f; 怎么办&#xff1…

【PS】画笔工具

目录 画直线 拾取颜色 改变画笔大小 改变画笔硬度 不透明度 流量 画笔预设 自定义图片做笔刷 工具预设 画笔面板 画直线 Shift键可画出直线只用点两个点就画出直线&#xff1a;先点一个点&#xff0c;按住shift&#xff0c;再在别处点一点&#xff0c;这时候直线就形…

Python 中如何使用pybind11调用C++

Python 中如何使用pybind11调用C1. pybind11简介与环境安装2. 求和函数3. STL和python内建数据类型的对应关系3.1 **返回vector**3.2 **返回struct**4. pybind11与numpy图像数据接口和速度对比&#xff1a;以图像rgb转化为gray的例子Reference: 混合编程&#xff1a;如何用pyb…

银联卡8583协议小额免密免签交易总结

之前做过金融支付这块儿。到过北京石景山区银行卡检测中心过检PBOC的level&#xff12;认证&#xff0c;去过上海银联总部和湖南银联对接银联卡和扫码支付。对金融支付和卡交易这块儿熟悉。现在这块儿知识用不上了总结下留作备忘&#xff0c;同时分享给有需要的人。 关于免密免…

【云原生 | Kubernetes 实战】12、K8s 四层代理 Service 入门到企业实战应用(下)

目录 一、创建 Service&#xff1a;type 类型是 NodePort 1.1 创建一个 pod 资源 1.2 创建 service&#xff0c;代理 pod 在集群外访问 service&#xff1a; 数据转发流程&#xff1a; 二、创建 Service&#xff1a;type 类型是 ExternalName 2.1 创建 pod 2.2 创建…

相关数据库

h2 需要用以下 初始化一下 第一次启动需要加入下面代码 h2 创建表 可以直接用jdbc 然后进行测试 不需要链接mysql redis 想要启动redis 现在 该目录下 输入俩个cmd 一个cmd 输入redis-cli 到启动太 输入 shutdown 然后再另一个cmd 输入 redis-server.exe redis.windows.con…

如何利用电商模式,灵活结合当地产品生态全力助农,实现乡村振兴

随着互联网时代的发展&#xff0c;人们的消费观念和消费习惯逐渐被改变&#xff0c;绿色环保观念深入人心&#xff0c;人们加大了对农产品的高要求和高需求&#xff0c;同时&#xff0c;近年来国家对农业的重视和政策支持&#xff0c;促进了农产品电商的蓬勃发展&#xff0c;已…

YOLOV7学习记录之原理+代码介绍

博主计划做一个目标检测跟踪项目&#xff0c;考虑使用YOLO系列模型来作为目标检测器&#xff0c;如今YOLO项目已经更新到了YOLOV7版本&#xff0c;因此便来学习一下相关原理&#xff0c;完成相关实验工作。 论文链接&#xff1a;https://arxiv.org/abs/2207.02696 网络结构 YO…

【字节码】Java Instrumentation 简介 以及 ASM 组合案例

1.概述 本文来自:深入理解JVM字节码 并且对其进行补充。 2.Java Instrumentation简介 JDK从1.5版本开始引人了java.lang.instrument 包,开发者可以更方便的实现字节码增强。其核心功能由java.lang.instrument.Instrumentation 提供,这个接口的方法提供了注册类文件转换器…

python列表添加元素append(),extend(),insert(),+list的区别及说明

这篇文章主要介绍了python列表添加元素append(),extend(), insert(),list的区别及说明&#xff0c;具有很好的参考价值&#xff0c;希望对大家有所帮助。 列表添加元素append(),extend(),insert(),list区别 回忆初学python的时候&#xff0c;对列表list添加元素时&#xff0c…

[附源码]Nodejs计算机毕业设计基于web技术的米其林轮胎管理系统Express(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程。欢迎交流 项目运行 环境配置&#xff1a; Node.js Vscode Mysql5.7 HBuilderXNavicat11VueExpress。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分…

C# 程序的组织

一 程序的组织 ① 名字控件 程序的逻辑组织&#xff1b; ② 嵌套类型 类中嵌套类型&#xff1b; ③ 程序集 程序的物理组织&#xff1b; 二 名字空间 1 名字控件的概念 逻辑划分&#xff1b;避免名字冲突&#xff1b; 2 名字空间的声明 namespace xxx.xxxxx{} 可嵌套 3 …

Jmeter 性能测试之阶梯式场景、波浪式场景

推荐阅读&#xff1a; [内部资源] 想拿年薪30W的软件测试人员&#xff0c;这份资料必须领取~ Python自动化测试全栈性能测试全栈&#xff0c;挑战年薪40W 1 阶梯式场景&#xff08;负载测试&#xff09; 该场景主要应用在负载测试里面&#xff0c;通过设定一定的并发线程数…

云游戏拉开产业化大幕

配图来自Canva可画 在过去十多年间&#xff0c;音乐和视频已经完成了线下存储到线上串流的变迁&#xff0c;VCD、CD、MP3也早已成为有历史记忆的收藏品&#xff0c;然而游戏业的“革命”——云游戏行业才刚刚开始。 尤其是随着5G和边缘计算的发展&#xff0c;更高的带宽、更低…

cubeIDE开发, 定时器TIM与外部中断NVIC实践案例

一、定时器功能 1.1 定时器分类 STM32 的定时器分为高级定时器、 通用定时器 、基本定时器三种。 这三个定时器成上下级的关系&#xff0c;即基本定时器有的功能通用定时器都有&#xff0c;而且还增加了向下、向上/向下计数器、PWM生成、输出比较、输入捕获等功能&#xff1b;而…

高并发编程之多线程锁和CallableFuture 接口

5 多线程锁 5.1 锁的八个问题演示 package com.xingchen.sync;import java.util.concurrent.TimeUnit;class Phone {public static synchronized void sendSMS() throws Exception {//停留4秒TimeUnit.SECONDS.sleep(4);System.out.println("------sendSMS");}publ…