首页 > 编程语言 >Python 使用 Selenium 如何抓取动态网页

Python 使用 Selenium 如何抓取动态网页

时间:2024-11-06 13:51:02浏览次数:3  
标签:网页 Python JavaScript Selenium 抓取 浏览器 动态 加载

Python 动态网页抓取:基础教程

在如今的网络中,许多网站是“动态”的,即网页内容不是静态的 HTML 文件,而是由 JavaScript 动态生成的。这种动态网页在数据抓取中带来了一些挑战,因为传统的 HTML 抓取方法无法抓取 JavaScript 生成的内容。在本教程中,我们将详细介绍如何使用 Python 抓取动态网页。

在这里插入图片描述

1. 什么是动态网页抓取?

动态网页抓取与传统静态网页抓取的主要区别在于:动态网页内容是通过 JavaScript 在客户端生成的。这意味着直接请求网页的 HTML 文件并不能得到完整的数据,需要等待 JavaScript 执行来加载数据。为了解决这个问题,动态网页抓取通常有以下几种方法:

  1. 使用自动化浏览器(如 Selenium):直接让浏览器执行 JavaScript,然后抓取加载后的网页内容。
  2. 分析网络请求:有些网站会在后台向服务器发送额外的请求(通常是 JSON 格式的数据),可以直接模拟这些请求以获取数据。
  3. 借助工具库(如 Pyppeteer):一些库能模拟浏览器行为,直接渲染页面以获得完整的内容。

2. 准备工作

在开始动态网页抓取之前,我们需要安装一些必要的库。

2.1 安装 Selenium

Selenium 是一个自动化测试工具,可以通过控制浏览器来执行 JavaScript,从而加载动态内容。安装 Selenium 后,还需要下载与之匹配的浏览器驱动(如 ChromeDriver)。

pip install selenium

下载 ChromeDriver(假设使用 Chrome 浏览器),然后将其路径添加到环境变量中。

2.2 安装 Pyppeteer

Pyppeteer 是另一个强大的动态抓取库,可以在无界面模式下执行浏览器任务。Pyppeteer 是 Puppeteer 的 Python 版本,Puppeteer 是一个用于 Node.js 的工具。

pip install pyppeteer

2.3 安装 Requests 和 BeautifulSoup

虽然 Requests 和 BeautifulSoup 主要用于静态网页抓取,但它们在获取动态网页中某些后台接口数据时也很有用。

pip install requests beautifulsoup4

3. 使用 Selenium 抓取动态网页

我们将通过 Selenium 抓取动态网页。首先,我们来看如何启动浏览器、访问网页并等待页面加载完成。假设我们要抓取一个动态加载的商品列表。

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time

# 设置 ChromeDriver 的路径
service = Service(executable_path='path/to/chromedriver')

# 初始化 Chrome 浏览器
driver = webdriver.Chrome(service=service)

# 打开目标网页
url = 'https://example.com/dynamic-page'
driver.get(url)

# 等待页面加载完成
try:
    # 等待特定元素加载,假设我们等待一个商品列表元素加载
    WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.CLASS_NAME, "product-list"))
    )

    # 抓取页面的 HTML 内容
    page_content = driver.page_source
    print(page_content)

finally:
    # 关闭浏览器
    driver.quit()

3.1 查找元素并提取数据

当页面加载完成后,我们可以使用 Selenium 提供的查找方法来定位和提取特定元素的内容。

# 查找商品名称的元素(假设 class 为 product-name)
products = driver.find_elements(By.CLASS_NAME, 'product-name')

for product in products:
    print(product.text)

3.2 滚动页面加载更多内容

一些动态网页会在用户滚动时加载更多内容,Selenium 可以通过模拟滚动来抓取更多的数据:

# 模拟滚动,加载更多内容
SCROLL_PAUSE_TIME = 2

# 获取当前页面的高度
last_height = driver.execute_script("return document.body.scrollHeight")

while True:
    # 滚动到底部
    driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")

    # 等待加载新内容
    time.sleep(SCROLL_PAUSE_TIME)

    # 获取新页面的高度
    new_height = driver.execute_script("return document.body.scrollHeight")
    if new_height == last_height:
        break  # 如果高度不变,说明已经加载完毕

    last_height = new_height

4. 使用 Pyppeteer 抓取动态网页

Pyppeteer 是 Puppeteer 的 Python 版本,它也可以用于抓取动态网页,并且支持无头浏览器(headless mode)。

4.1 简单示例

以下是一个使用 Pyppeteer 抓取动态内容的简单示例:

import asyncio
from pyppeteer import launch

async def fetch_dynamic_content(url):
    # 启动浏览器
    browser = await launch(headless=True)
    page = await browser.newPage()
    
    # 打开网页
    await page.goto(url)
    
    # 等待特定元素加载完成
    await page.waitForSelector('.product-list')

    # 获取页面内容
    content = await page.content()
    print(content)

    # 关闭浏览器
    await browser.close()

# 启动异步任务
url = 'https://example.com/dynamic-page'
asyncio.get_event_loop().run_until_complete(fetch_dynamic_content(url))

4.2 截图与调试

Pyppeteer 还支持截图功能,可以帮助我们进行调试。

await page.screenshot({'path': 'screenshot.png'})

5. 使用 Requests 抓取动态网页中的 API 数据

许多动态网站在加载内容时,实际上会向后端发送请求获取数据。我们可以在浏览器的“网络”面板中找到这些请求的 URL,并用 Requests 库模拟这些请求来抓取数据。

import requests

# 目标 URL(在浏览器网络面板中找到的 API 请求 URL)
url = 'https://example.com/api/products'

# 发送请求并获取数据
response = requests.get(url)
data = response.json()

# 打印数据
print(data)

6. 动态抓取的常见问题与技巧

6.1 JavaScript 渲染的内容未加载

如果页面中的内容是通过 JavaScript 渲染的,那么直接用 requests 获取 HTML 不会包含这些内容。这种情况可以考虑:

  • 使用 Selenium 或 Pyppeteer,让浏览器真正执行 JavaScript 并加载内容。
  • 找到 JavaScript 背后的 API 请求,直接获取数据。

6.2 遇到验证码或反爬虫措施

许多网站都有反爬虫措施。遇到这种情况,可以尝试:

  • 调整请求频率:增加请求之间的间隔,避免高频率访问。
  • 使用代理:避免使用固定 IP 地址。
  • 设置浏览器头:在请求中添加浏览器头部信息,模拟正常的浏览器访问。
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}
response = requests.get(url, headers=headers)

7. 动态抓取的实际应用场景

  • 电商数据采集:抓取产品列表和详细信息。
  • 社交媒体分析:获取社交平台的动态内容,如推文或评论。
  • 新闻数据收集:抓取新闻网站动态加载的新闻条目。

8. 小结

动态网页抓取比静态网页抓取复杂得多,因为它需要模拟浏览器行为来执行 JavaScript。然而,使用 Selenium 和 Pyppeteer 等工具,我们可以轻松地抓取动态网页内容。此外,分析网络请求并直接抓取 API 数据也可以是更高效的方式。希望通过本文的介绍,您能够了解 Python 动态网页抓取的基础知识,并运用这些工具来获取所需的数据。

标签:网页,Python,JavaScript,Selenium,抓取,浏览器,动态,加载
From: https://blog.csdn.net/chusheng1840/article/details/143568775

相关文章

  • Selenium简介
    Selenium是一个广泛应用的自动化测试工具,专门用于Web应用的测试。它提供了多种功能和灵活的操作方式,使测试人员可以通过编程方式模拟用户与Web浏览器的交互。以下是一些Selenium的基础介绍材料:1.什么是Selenium?Selenium是一个开源的Web自动化测试框架,可以通过编......
  • Python 继承、多态、封装、抽象
    面向对象编程(OOP)是Python中的一种重要编程范式,它通过类和对象来组织代码。OOP的四个核心概念是继承(Inheritance)、多态(Polymorphism)、封装(Encapsulation)和数据抽象(DataAbstraction)。下面将详细介绍这四个概念。继承(Inheritance)继承是面向对象编程(OOP)的一个基本概念,它允......
  • [记录]安装 Python 中SPAM库失败
    报错信息:×pythonsetup.pyegg_infodidnotrunsuccessfully.│exitcode:1╰─>[41linesofoutput]runningegg_infocreating/private/var/folders/l9/f9rjm65s07bdf55y5xyk9f2c0000gn/T/pip-pip-egg-info-o3ic4gdp/progressbar.egg-infowriting/private/var/fo......
  • 如何通过Python SDK更新Collection中已存在的Doc
    本文介绍如何通过PythonSDK更新Collection中已存在的Doc。说明若更新Doc时指定id不存在,则本次更新Doc操作无效如只更新部分属性fields,其他未更新属性fields默认被置为NonePythonSDK1.0.11版本后,更新Doc时vector变为非必填项前提条件已创建Cluster:创建Cluster。......
  • 基于大数据 Python 校园食堂订餐数据分析系统(源码+LW+部署讲解+数据库+ppt)
    !!!!!!!!!选题不知道怎么选不清楚自己适合做哪块内容都可以免费来问我避免后期給自己答辩找麻烦增加难度(部分学校只有一次答辩机会没弄好就延迟毕业了)会持续一直更新下去有问必答一键收藏关注不迷路源码获取:https://pan.baidu.com/s/1aRpOv3f2sdtVYOogQjb8jg?pwd=jf1d提取码:......
  • 100种算法【Python版】第51篇——希尔排序
    本文目录1算法步骤2算法示例3python代码3.1代码说明3.2复杂度分析4算法优化4.1Shell原始增量序列4.2Hibbard增量序列4.3Knuth增量序列4.4Sedgewick增量序列4.5Tokuda增量序列4.6Pratt增量序列5不同的增量序列的效率对比希尔......
  • Python 常用操作代码
    参考教程地址:https://www.runoob.com/python/python-tutorial.html常用代码总结#获取路径的文件名及其后缀filename=os.path.basename(path)filename_without_ext,ext=os.path.splitext(filename)#获取父目录路径parent_folder_path=os.path.dirname(path)pa......
  • Python socket传输图像文件
    客户端发送图像文件importsocketdata=numpy.frombuffer(stringData,numpy.uint8)#将获取到的字符流数据转换成1维数组#decimg=cv2.imdecode(data,cv2.COLOR_BGR2GRAY)#将数组解码成图像#cv2.imwrite("./test.jpg",decimg)#imencode()将图片格式转换(编码)成流数据,......
  • Python(logging.getLogger().info())
    目录1.getLogger()函数2.info()方法3.配置日志级别4.示例代码5.其他日志级别方法6.使用场景logging.getLogger().info()是Python的logging模块中用于记录信息级别(infolevel)日志的函数。logging是一个Python内置模块,提供了日志记录功能。它支持不同的日志级别,不......
  • Python进程管理:创建和协调多进程的深入指南
    在Python中,进程是操作系统进行资源分配和调度的一个独立单位。与线程相比,进程拥有独立的内存空间,这使得它们在执行多任务时更加稳定,但也带来了更高的资源消耗。本文将深入探讨如何在Python中创建和管理进程,包括详细的代码示例,帮助你掌握多进程编程的技巧。1.理解进程进程......