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

【动态网页抓取】 :用Python抓取所有内容的指南

一、说明

        您在抓取动态网页内容时是否得到了糟糕的结果?不仅仅是你。对于标准抓取工具来说,爬网动态数据是一项具有挑战性的任务(至少可以说)。这是因为当发出HTTP请求时,响应程序的某些部分JavaScript在后台运行,而 抓取动态网站需要在浏览器中呈现整个页面并提取目标信息。

        加入我们的分步教程,了解有关使用 Python 进行动态网页抓取的所有信息——该做什么和不该做什么、挑战和解决方案,以及介于两者之间的一切。

 

二、什么是动态网站?

        动态网站是指没有直接在其静态HTML中包含所有内容的网站。它使用服务器端或客户端来显示数据,有时基于用户的操作(例如,单击、滚动等)。

        简而言之,这些网站在每个服务器请求中显示不同的内容或布局。这有助于缩短加载时间,因为用户每次想要查看“新”内容时都无需重新加载相同的信息。

        如何识别它们?一种方法是在浏览器的命令面板中禁用 JavaScript。如果网站是动态的,内容将消失。

        让我们以 Saleor React Storefront 为例。这是它的首页的样子:

        注意标题、图像和艺术家姓名。

        现在,让我们使用以下步骤禁用 JavaScript:

  1. 检查页面:右键单击并选择“检查”以打开“DevTools 窗口”。
  2. 导航到命令面板:CTRL/CMD + SHIFT + P。
  3. 搜索“JavaScript”。
  4. 单击禁用 JavaScript
  5. 点击刷新。

结果如何?见下文:

你自己看!禁用 JavaScript 会删除所有动态 Web 内容。

三、使用 Python 进行动态网页抓取的替代方案

        所以,你想用Python抓取动态网站......

        由于 Beautiful Soup 或 Requests 等库不会自动获取动态内容,因此您有两个选项来完成任务:

  • 将内容馈送到标准库。
  • 在抓取时执行页面的内部 JavaScript。

        但是,并非所有动态页面都相同。有些通过 JS API 呈现内容,可以通过检查“网络”选项卡来访问这些内容。其他人将JS渲染的内容作为JSON存储在DOM(文档对象模型)中的某个位置。

        好消息是,我们可以解析 JSON 字符串以在这两种情况下提取必要的数据。

        请记住,在某些情况下,这些解决方案不适用。对于此类网站,您可以使用无头浏览器来呈现页面并提取所需的数据。

        使用 Python 抓取动态网页的替代方法是:

  • 手动查找数据并解析 JSON 字符串。
  • 使用无头浏览器执行页面的内部JavaScript(例如,Selenium或Pyppeteer,Puppeteer的非官方Python端口)。

四、在 Python 中抓取动态网站的最简单方法是什么?

        的确,无头浏览器可能很慢且性能密集。但是,他们取消了对网络抓取的所有限制。也就是说,如果您不计算反机器人检测。而且您不应该这样做,因为我们已经告诉您如何绕过此类保护。

        手动查找数据并解析 JSON 字符串假定可以访问动态数据的 JSON 版本。不幸的是,情况并非总是如此,尤其是在涉及高级单页应用程序 (SPA) 时。

        更不用说模仿 API 请求是不可扩展的。他们通常需要 cookie 和身份验证以及其他可以轻松阻止您的限制。

        在 Python 中抓取动态网页的最佳方法取决于您的目标和资源。如果您可以访问网站的 JSON 并希望提取单个页面的数据,则可能不需要无头浏览器。

        然而,除了这一小部分情况,大多数时候使用美丽的汤和硒是你最好和最简单的选择。

        是时候弄脏我们的手了!准备好编写一些代码,并准确地了解如何在 Python 中抓取动态网站!

五、先决条件

        若要遵循本教程,需要满足一些要求。我们将使用以下工具:

  • Python 3:最新版本的 Python 将运行得最好。在撰写本文时,这是 3.11.2。
  • Web驱动程序管理器:这将确保浏览器和驱动程序的版本匹配。您不必为此目的手动下载 Web 驱动程序。
pip install selenium webdriver-manager 

        您现在拥有所需的一切。我们走吧!

六、方法#1:使用Beautiful Soup使用Python进行动态网页抓取

        Beautiful Soup可以说是用于抓取HTML数据的最流行的Python库。

        要使用它提取信息,我们需要目标页面的 HTML 字符串。但是,动态内容并不直接存在于网站的静态 HTML 中。这意味着 Beautiful Soup 无法访问 JavaScript 生成的数据

        这是一个解决方案:如果网站使用 AJAX 请求加载内容,则可以从 XHR 请求中提取数据。

七、方法#2:使用Selenium在Python中抓取动态网页

        要了解Selenium如何帮助您抓取动态网站,首先,我们需要检查常规库(例如)如何与它们交互。Requests

        我们将使用 Angular 作为我们的目标网站:

        让我们尝试刮擦它,看看结果。在此之前,我们必须安装可以使用该命令执行的库。RequestsRequestspip

pip install requests 

        我们的代码如下所示:

import requests  
url = 'https://angular.io/'  
response = requests.get(url)  
html = response.text  
print(html)

如您所见,仅提取了以下 HTML:

<noscript> <div class="background-sky hero"></div> <section id="intro" style="text-shadow: 1px 1px #1976d2;"> <div class="hero-logo"></div> <div class="homepage-container"> <div class="hero-headline">The modern web<br>developer's platform</div> </div> </section> <h2 style="color: red; margin-top: 40px; position: relative; text-align: center; text-shadow: 1px 1px #fafafa; border-top: none;"> <b><i>This website requires JavaScript.</i></b> </h2> 
</noscript>

        但是,检查网站显示的内容比检索的内容多。

        当我们在页面上禁用JavaScript时,就会发生这种情况:

        这正是能够返回的原因。该库在解析来自网站静态 HTML 的数据时不会察觉到任何错误,这正是它创建时要做的事情。Requests

        在这种情况下,不可能获得与网站上显示的结果相同的结果。你能猜出为什么吗?没错,这是因为这是一个动态网页。

        要访问整个内容并提取我们的目标数据,我们必须渲染 JavaScript。

        是时候用硒动态网页抓取来纠正它了。

        我们将使用以下脚本快速抓取目标网站:

from selenium import webdriver 
from selenium.webdriver.chrome.service import Service as ChromeService 
from webdriver_manager.chrome import ChromeDriverManager url = 'https://angular.io/' driver = webdriver.Chrome(service=ChromeService( ChromeDriverManager().install())) driver.get(url) print(driver.page_source)

        你有它!页面的完整 HTML,包括动态 Web 内容。

        祝贺!您刚刚抓取了您的第一个动态网站。

八、选择硒(Selenium)中的元素

        有不同的方法可以访问硒中的元素。我们在 Python 中的硒网络抓取指南中深入讨论了这个问题。

        不过,我们将通过一个例子来解释这一点。让我们只选择目标网站上的 H2:

        在开始之前,我们需要检查网站并确定要提取的元素的位置。

        我们可以看到,这些头条新闻很常见。我们复制它并映射 H2s 以使用 Chrome 驱动程序获取元素。class="text-container"

粘贴此代码:

from selenium import webdriver 
from selenium.webdriver.common.by import By 
from selenium.webdriver.chrome.service import Service as ChromeService 
from webdriver_manager.chrome import ChromeDriverManager # instantiate options 
options = webdriver.ChromeOptions() # run browser in headless mode 
options.headless = True # instantiate driver 
driver = webdriver.Chrome(service=ChromeService( ChromeDriverManager().install()), options=options) # load website 
url = 'https://angular.io/' # get the entire website content 
driver.get(url) # select elements by class name 
elements = driver.find_elements(By.CLASS_NAME, 'text-container') 
for title in elements: # select H2s, within element, by tag name heading = title.find_element(By.TAG_NAME, 'h2').text # print H2s print(heading)

        您将获得以下内容:

"DEVELOP ACROSS ALL PLATFORMS" 
"SPEED & PERFORMANCE" 
"INCREDIBLE TOOLING" 
"LOVED BY MILLIONS"

        很好,很容易!您现在可以毫不费力地用硒抓取动态网站。

九、如何用硒抓取无限滚动网页

        当用户向下滚动到页面底部时,某些动态页面会加载更多内容。这些被称为“精细滚动网站”。爬行它们更具挑战性。为此,我们需要指示我们的蜘蛛滚动到底部,等待所有新内容加载,然后才开始抓取。

        通过一个例子来理解这一点。让我们使用刮擦俱乐部的示例页面。

        此脚本将滚动浏览前 20 个结果并提取其标题:

from selenium import webdriver 
from selenium.webdriver.common.by import By 
from selenium.webdriver.chrome.service import Service as ChromeService 
from webdriver_manager.chrome import ChromeDriverManager 
import time options = webdriver.ChromeOptions() 
options.headless = True 
driver = webdriver.Chrome(service=ChromeService( ChromeDriverManager().install()), options=options) # load target website 
url = 'https://scrapingclub.com/exercise/list_infinite_scroll/' # get website content 
driver.get(url) # instantiate items 
items = [] # instantiate height of webpage 
last_height = driver.execute_script('return document.body.scrollHeight') # set target count 
itemTargetCount = 20 # scroll to bottom of webpage 
while itemTargetCount > len(items): driver.execute_script('window.scrollTo(0, document.body.scrollHeight);') # wait for content to load time.sleep(1) new_height = driver.execute_script('return document.body.scrollHeight') if new_height == last_height: break last_height == new_height # select elements by XPath elements = driver.find_elements(By.XPATH, "//div[@class='card-body']/h4/a") h4_texts = [element.text for element in elements] items.extend(h4_texts) # print title print(h4_texts)

备注:为无限滚动页面设置目标计数非常重要,这样您就可以在某个时候结束脚本。

在前面的示例中,我们使用了另一个选择器:。它将基于 XPath 而不是类和 ID 来定位元素,如前所述。检查页面,右键单击包含要抓取的元素的 ,然后选择复制路径By.XPath<div>

您的结果应如下所示:

['Short Dress', 'Patterned Slacks', 'Short Chiffon Dress', 'Off-the-shoulder Dress', ...]

你有它,前 4 种产品的 H20!

备注:使用硒进行动态网页抓取可能会因硒的持续更新而变得棘手。最好通过最新的变化。

十、结论

动态网页无处不在。因此,您在数据提取工作中遇到它们的可能性足够高。请记住,熟悉其结构将帮助您确定检索目标信息的最佳方法。

我们在本文中探讨的所有方法都有其自身的缺点和缺点。所以,看看ZenRows必须提供什么。该解决方案允许您使用简单的 API 调用抓取动态网站。立即免费试用,节省自己的时间和资源。

你觉得内容有帮助吗?传播这个词并在Twitter,LinkedIn或Facebook上分享。

本文最初发表于 ZenRows: Dynamic Web Pages Scraping with Python: Guide to Scrape All Content

相关文章:

【动态网页抓取】 :用Python抓取所有内容的指南

一、说明 您在抓取动态网页内容时是否得到了糟糕的结果&#xff1f;不仅仅是你。对于标准抓取工具来说&#xff0c;爬网动态数据是一项具有挑战性的任务&#xff08;至少可以说&#xff09;。这是因为当发出HTTP请求时&#xff0c;响应程序的某些部分JavaScript在后台运行&…...

Spring Boot数据访问基础知识与JDBC简单实现

目录 Spring Boot数据访问基础知识 Spring Data ORM JDBC JPA JDBC简单实现 步骤1&#xff1a;新建Maven项目&#xff0c;添加依赖 步骤2&#xff1a;配置数据源—让程序可以访问到 步骤3&#xff1a;配置数据源—让IDEA可以访问到 步骤4&#xff1a;添加数据库和表 …...

ubuntu添加万能头文件

ubuntu的C头文件目录为/usr/include 在/usr/include下新建文件夹 bits sudo mkdir bits进入bits&#xff0c;新建stdc.h&#xff0c;并修改权限为744/777 cd bits;sudo touch stdc.h;sudo chmod 777 stdc.h将以下内容粘贴到stdc.h&#xff0c;保存退出 // C includes used …...

聊一聊关于前端语法 ?? 的那些事

当我们在编写前端代码时&#xff0c;语法是非常重要的。正确的语法可以确保我们的代码能够正常运行&#xff0c;并且易于维护和理解。在本文中&#xff0c;我们将探讨一些前端语法的问题&#xff0c;例如空值合并运算符&#xff08;??&#xff09;。 空值合并运算符是ES2020…...

宝塔Linux面板升级“获取更新包失败”怎么解决?

宝塔Linux面板执行升级命令后失败&#xff0c;提示“获取更新包失败&#xff0c;请稍后更新或联系宝塔运维”如何解决&#xff1f;新手站长分享宝塔面板升级失败的解决方法&#xff1a; 宝塔面板升级失败解决方法 1、使用root账户登录到你的云服务器上&#xff0c;宝塔Linux面…...

训练强化学习的经验回放策略:experience replay

经验回放&#xff1a;Experience Replay&#xff08;训练DQN的一种策略&#xff09; 优点&#xff1a;可以重复利用离线经验数据&#xff1b;连续的经验具有相关性&#xff0c;经验回放可以在离线经验BUFFER随机抽样&#xff0c;减少相关性&#xff1b; 超参数&#xff1a;Rep…...

uniapp学习

1 简单的表单校验 <!--uniapp:参考模板和字段生成页面 字段stuNumber 输入框 学号stuName 输入框 学生姓名teacher 输入框 辅导员submitDate 日期选择 填报日期morningTemperature 输入框&#xff08;数字校验一位小数&#xff09; 早上体温noonTemperature 输入框&…...

机器学习深度学习——数值稳定性和模型化参数(详细数学推导)

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位即将上大四&#xff0c;正专攻机器学习的保研er &#x1f30c;上期文章&#xff1a;机器学习&&深度学习——Dropout &#x1f4da;订阅专栏&#xff1a;机器学习&&深度学习 希望文章对你们有所帮助 这一部…...

layui 整合UEditor 百度编辑器

layui 整合UEditor 百度编辑器 第一步&#xff1a;下载百度编辑器并配置好路径 百度编辑器下载地址&#xff1a;http://fex.baidu.com/ueditor/ 第二步&#xff1a;引入百度编辑器 代码如下&#xff1a; <div class"layui-form-item layui-form-text"><…...

1、sparkStreaming概述

1、sparkStreaming概述 1.1 SparkStreaming是什么 它是一个可扩展&#xff0c;高吞吐具有容错性的流式计算框架 吞吐量&#xff1a;单位时间内成功传输数据的数量 之前我们接触的spark-core和spark-sql都是处理属于离线批处理任务&#xff0c;数据一般都是在固定位置上&…...

【Spring Boot】Spring Boot 集成 RocketMQ 实现简单的消息发送和消费

文章目录 前言基本概念消息和主题相关发送普通消息 发送顺序消息RocketMQTemplate的API介绍参考资料&#xff1a; 前言 本文主要有以下内容&#xff1a; 简单消息的发送顺序消息的发送RocketMQTemplate的API介绍 环境搭建&#xff1a; RocketMQ的安装教程&#xff1a;在官网…...

uniapp:图片验证码检验问题处理

图形验证码功能实现 uniapp&#xff1a;解决图形验证码问题及利用arraybuffer二进制转base64格式图片&#xff08;后端传的图片数据形式&#xff1a;x00\x10JFIF\x00\x01\x02\x00…&#xff09;_❆VE❆的博客-CSDN博客 UI稿&#xff1a; 需求&#xff1a;向后端请求验证码图片&…...

将Visio和Excel导出成没有白边的PDF文件

1、VISIO如何无白边导出pdf格式 在使用Latex时&#xff0c;要导入矢量图eps格式。但是VISIO无法输出eps格式&#xff0c;这就需要将其导出为pdf。但是导出pdf时&#xff0c;往往会有大量的白边。VISIO无白边导出pdf格式的方法如下&#xff1a; 1.文件——开发工具——显示sha…...

String类及其工具类

一、String类 1.字符串对象 String str new String("hello");String对象是final修饰的&#xff0c;不可修改的&#xff0c;修改后的字符串对象是另外一个对象&#xff0c;只是修改了引用地址。每次创建都会创建一个新的对象。 2. 字面量 String s "hello&…...

踩坑(5)整合kafka 报错 java.net.UnknownHostException: 不知道这样的主机

java.net.UnknownHostException: 不知道这样的主机。 (5c0c3c629db9)at java.base/java.net.Inet6AddressImpl.lookupAllHostAddr(Native Method) ~[na:na]at java.base/java.net.InetAddress$PlatformNameService.lookupAllHostAddr(InetAddress.java:933) ~[na:na]at java.ba…...

rust持续学习 get_or_insert_with

通常使用一个值 if(xnull)xsome_valid_value 忽然今天看见一段代码 pub fn get_id() -> u64 { let mut res struct.data.borrow_mut(); *res.get_or_insert_with(||{let mut xx ...... some logiclet id xx.id; id}); }感觉这个名字蛮奇怪的 insert 然后翻了一下代码&a…...

卡尔曼滤波 | Matlab实现无迹kalman滤波仿真

文章目录 效果一览文章概述研究内容程序设计参考资料效果一览 文章概述 卡尔曼滤波 | Matlab实现无迹kalman滤波仿真 研究内容 无迹kalman滤波(UKF)不是采用的将非线性函数线性化的做法。无迹kalman仍然采用的是线性kalman滤波的架构,对于一步预测方程,使用无迹变换(UT)来…...

C++---list常用接口和模拟实现

list---模拟实现 list的简介list函数的使用构造函数迭代器的使用list的capacitylist element accesslist modifiers list的模拟实现构造函数&#xff0c;拷贝构造函数和迭代器begin和endinsert和eraseclear和析构函数 源码 list的简介 list是用双向带头联表实现的一个容器&…...

[openCV]基于赛道追踪的智能车巡线方案V1

import cv2 as cv import os import numpy as npimport time# 遍历文件夹函数 def getFileList(dir, Filelist, extNone):"""获取文件夹及其子文件夹中文件列表输入 dir&#xff1a;文件夹根目录输入 ext: 扩展名返回&#xff1a; 文件路径列表""&quo…...

SpringIoc-个人学习笔记

Spring的Ioc、DI、AOP思想 Ioc Ioc思想&#xff1a;Inversion of Control&#xff0c;控制反转&#xff0c;在创建Bean的权利反转给第三方 DI DI思想&#xff1a;Dependency Injection&#xff0c;依赖注入&#xff0c;强调Bean之间的关系&#xff0c;这种关系由第三方负责去设…...

【一文搞懂泛型】

3.3泛型 3.3.1泛型出现的背景 泛型出现的背景有两点&#xff1a; 第一点是在集合容器中&#xff0c;如果没有指定对应类型的话&#xff0c;那么底层的元素就是object&#xff0c;要对容器中的元素进行存取的时候&#xff0c;取出来的同时需要进行类型转换&#xff0c;如果有…...

概念解析 | 利用MIMO雷达技术实现高性能目标检测的关键技术解析

注1:本文系“概念解析”系列之一,致力于简洁清晰地解释、辨析复杂而专业的概念。本次辨析的概念是:MIMO雷达目标检测技术 参考资料:何子述, 程子扬, 李军, 等. 集中式 MIMO 雷达研究综述[J]. 雷达学报, 2022, 11(5): 805-829. 利用MIMO雷达技术实现高性能目标检测的关键技术解…...

Grafana制作图表-自定义Flink监控图表

简要 有时候我们在官网的Grafana下载的图表是这样的&#xff0c;如下图 #算子的处理时间&#xff0c;就是处理数据的延迟数据抓取&#xff0c;这个的说明看下下面的文章 metrics.latency.interval: 60 metrics.reporter.promgateway.class: org.apache.flink.metrics.prometh…...

【TypeScript】初识TypeScript和变量类型介绍

TypeScript 1&#xff0c;TypeScript是什么?2&#xff0c;类型的缺失带来的影响3&#xff0c;Ts搭建环境-本博主有专门的文章专说明这个4&#xff0c;使用tsc对ts文件进行编译5&#xff0c;TS运行初体验简化Ts运行步骤解决方案1解决方案2&#xff08;常见&#xff09; 开始学习…...

阿里云瑶池 PolarDB 开源官网焕新升级上线

导读近日&#xff0c;阿里云开源云原生数据库 PolarDB 官方网站全新升级上线。作为 PolarDB 开源项目与开发者、生态伙伴、用户沟通的平台&#xff0c;将以开放、共享、促进交流为宗旨&#xff0c;打造开放多元的环境&#xff0c;以实现共享共赢的目标。 立即体验全新官网&…...

泡水书为什么不能再出售

近日&#xff0c;京津冀持续强降雨&#xff0c;多家出版机构位于涿州等地的图书库房受到影响。 中图网11日发文称&#xff0c;其位于涿州的仓储中心被洪水淹了&#xff0c;一库房有400多万册的书籍。 网友纷纷在文章下暖心留言&#xff1a;注意人身安全&#xff0c;泡水的书也…...

Mac 执行 .sh命令报错 command not found

使用终端执行.sh命令&#xff0c;可输入&#xff1a; ./FileName.sh如果提示 Permission denied 权限不足&#xff0c;可增加sudo&#xff0c;命令如下&#xff1a; sudo ./FileName.sh如果提示 command not found 可以这样: chmod ux *.sh sudo ./FileName.sh...

postgresql 使用之 存储架构 触摸真实数据的存储结构以及组织形式,存入数据库的数据原来在这里

存储架构 ​专栏内容&#xff1a; postgresql内核源码分析 手写数据库toadb 并发编程 个人主页&#xff1a;我的主页 座右铭&#xff1a;天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物. 概述 postgresql 数据库服务运行时&#xff0c;数据在磁…...

Node.Js安装与配置教程

目录 1.下载官网 2.选择安装路径 3.添加环境变量 4.验证是否安装成功 5.修改模块下载位置 (1)查看npm默认存放位置 6.在node.js安装目录下&#xff0c;创建两个文件夹 7.修改默认文件夹 8.测试默认位置是否更改成功 9.安装报错解决办法 10.路径未更改成功解决办法 …...

Element-Plus DatePicker获取时间戳

文章目录 0、先上答案1、渔&#xff1f;1-1 Element-Plus 官网1-2 溯源 Day.js 0、先上答案 <!-- 秒 --><el-date-pickerv-model"timeStamp"type"datetime"value-format"X"/><!-- 毫秒 --><el-date-pickerv-model"tim…...