0

0

使用Selenium和Python执行异步Fetch请求并获取响应

聖光之護

聖光之護

发布时间:2025-11-01 11:46:06

|

471人浏览过

|

来源于php中文网

原创

使用selenium和python执行异步fetch请求并获取响应

本文详细介绍了如何利用Selenium的`execute_async_script`方法在Python中执行JavaScript的`fetch`请求,并高效地获取其异步响应。内容涵盖了设置自定义HTTP头、处理GET/POST请求以及从浏览器环境无缝检索数据到Python的实用技巧。

在自动化测试和网页抓取场景中,我们经常需要模拟浏览器行为来发送HTTP请求,并获取响应数据。Selenium作为一款强大的浏览器自动化工具,通常通过模拟用户操作来与页面交互。然而,当需要直接在浏览器环境中执行JavaScript的fetch API来发送具有自定义HTTP头(如CUSTOM_HEADER_1、CUSTOM_HEADER_2等)的GET或POST请求,并获取其异步返回的JSON数据时,会遇到一些挑战。

Selenium中Fetch请求的挑战

直接使用driver.execute_script()执行fetch请求时,由于fetch是一个异步操作,它会立即返回一个JavaScript Promise对象,而不是请求的实际数据。这意味着Python端无法直接获取到Promise解析后的结果。为了解决这一问题,我们需要利用Selenium提供的异步脚本执行机制。

核心解决方案:execute_async_script

Selenium的execute_async_script()方法专门用于执行异步JavaScript代码。它允许JavaScript代码在完成其异步操作后,通过调用一个特殊的callback函数将结果返回给Python。这是处理fetch请求异步特性的关键。

立即学习Python免费学习笔记(深入)”;

当execute_async_script()被调用时,它会向JavaScript环境注入一个回调函数作为其第一个参数(通常命名为arguments[0])。JavaScript代码在执行fetch请求并处理完响应后,只需将最终结果作为参数传递给这个callback函数,Selenium就会等待该回调被执行,并将传递给回调函数的值作为execute_async_script()的返回值返回给Python。

讯飞星火
讯飞星火

科大讯飞推出的多功能AI智能助手

下载

实现步骤与代码示例

下面我们将通过一个完整的Python示例,演示如何使用execute_async_script来执行带有自定义头的GET和POST fetch请求,并获取JSON响应。

1. Python环境准备与WebDriver初始化

首先,我们需要导入必要的Selenium模块,并配置WebDriver。这里以Chrome为例,并展示如何尝试配置代理(尽管需要注意其对fetch请求的潜在局限性)。

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
import json

# 示例代理设置 (注意:对于execute_async_script发起的fetch,此设置可能不总是生效)
# 如果fetch请求需要通过代理,通常需要更复杂的网络拦截或直接在fetch选项中指定代理
proxy_server_url = "127.0.0.1:8888"
chrome_options = webdriver.ChromeOptions()
# chrome_options.add_argument('--proxy-server=%s' % proxy_server_url)
chrome_options.add_argument("ignore-certificate-errors")
chrome_options.add_argument("--headless") # 可选:无头模式运行

driver = webdriver.Chrome(options=chrome_options)

# 设置异步脚本的超时时间,默认为0,需要手动设置
driver.set_script_timeout(10) # 设置为10秒

# 导航到一个空白页或任意页面,以确保浏览器环境已准备好执行JS
driver.get("about:blank")
print("WebDriver initialized and navigated to about:blank.")

2. 执行异步Fetch请求(GET示例)

我们将构建一个JavaScript脚本,用于执行GET请求,并期望返回JSON数据。

# 示例:GET请求,获取JSON数据
get_url = "https://jsonplaceholder.typicode.com/posts/1" # 示例URL
get_headers = {
    "Accept": "application/json",
    "Custom-Header-GET": "get_value_123"
}

# 构建JavaScript fetch请求脚本
js_script_get = """
let callback = arguments[0]; // Selenium注入的回调函数
let url = arguments[1];
let headers = arguments[2];

fetch(url, {
    method: 'GET',
    headers: headers
})
.then(response => {
    if (!response.ok) {
        // 如果响应状态码不是2xx,抛出错误
        return response.text().then(text => { throw new Error(`Network response was not ok: ${response.status} - ${text}`); });
    }
    return response.json(); // 尝试解析为JSON
})
.then(data => callback(data)) // 将解析后的数据通过回调返回给Python
.catch(error => callback({ error: error.message })); // 捕获错误并返回错误信息
"""

print(f"\nExecuting GET request to: {get_url}")
try:
    response_data_get = driver.execute_async_script(js_script_get, get_url, get_headers)
    print("GET Request Response (Python):")
    print(json.dumps(response_data_get, indent=2, ensure_ascii=False))
except TimeoutException:
    print("GET request timed out.")
except Exception as e:
    print(f"An error occurred during GET request: {e}")

3. 执行异步Fetch请求(POST示例)

接着,我们演示如何发送一个带有请求体的POST请求。

# 示例:POST请求,发送JSON数据
post_url = "https://jsonplaceholder.typicode.com/posts" # 示例URL
post_data = {"title": "foo", "body": "bar", "userId": 1}
post_headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
    "Custom-Header-POST": "post_value_456"
}

# 构建JavaScript fetch请求脚本
js_script_post = """
let callback = arguments[0];
let url = arguments[1];
let headers = arguments[2];
let body = arguments[3];

fetch(url, {
    method: 'POST',
    headers: headers,
    body: JSON.stringify(body) // 将POST数据转换为JSON字符串
})
.then(response => {
    if (!response.ok) {
        return response.text().then(text => { throw new Error(`Network response was not ok: ${response.status} - ${text}`); });
    }
    return response.json();
})
.then(data => callback(data))
.catch(error => callback({ error: error.message }));
"""

print(f"\nExecuting POST request to: {post_url}")
try:
    response_data_post = driver.execute_async_script(js_script_post, post_url, post_headers, post_data)
    print("POST Request Response (Python):")
    print(json.dumps(response_data_post, indent=2, ensure_ascii=False))
except TimeoutException:
    print("POST request timed out.")
except Exception as e:
    print(f"An error occurred during POST request: {e}")

# 完成后关闭WebDriver
driver.quit()
print("\nWebDriver closed.")

代码解析

  • *`driver.execute_async_script(js_script, args)**: 这是核心方法。js_script是将在浏览器中执行的JavaScript代码。*args是传递给JavaScript脚本的参数。在JavaScript中,这些参数通过arguments[0],arguments[1]等访问。arguments[0]`总是Selenium注入的回调函数。
  • JavaScript fetch API:
    • fetch(url, options): 发送HTTP请求。
    • options.method: 指定HTTP方法,如'GET'或'POST'。
    • options.headers: 一个包含请求头的JavaScript对象。键值对对应HTTP头名称和值。
    • options.body: 对于POST等请求,用于发送请求体。如果发送JSON数据,需要使用JSON.stringify()将其转换为字符串。
  • Promise链式调用:
    • .then(response => ...): 处理fetch返回的响应对象。
    • response.ok: 检查响应状态码是否在200-299之间。
    • response.json() / response.text(): 将响应体解析为JSON对象或纯文本。这些也是异步操作,返回Promise。
    • .then(data => callback(data)): 在数据成功解析后,通过callback函数将数据返回给Python。
    • .catch(error => callback({ error: error.message })): 捕获fetch或响应处理过程中的任何错误,并将错误信息返回给Python。

注意事项

  1. 代理设置的局限性: 虽然可以在ChromeOptions中设置浏览器级代理,但通过execute_async_script直接发起的fetch请求,有时可能不会完全遵循这些代理设置。这取决于浏览器内部的实现和fetch API的行为。如果代理是关键,可能需要考虑在fetch请求中直接配置代理(如果API支持,但标准fetch不支持直接配置代理),或者使用其他网络拦截工具(如Selenium Wire)来捕获和修改请求。
  2. 数据类型转换: JavaScript通过callback返回的数据会由Selenium自动转换为Python类型。例如,JavaScript对象会被转换为Python字典,数组转换为列表,字符串转换为字符串。确保JavaScript返回的数据结构与Python期望的匹配。
  3. 超时处理: execute_async_script默认的超时时间可能很短或为0。务必使用driver.set_script_timeout()来设置一个合理的超时时间,以避免因网络延迟或脚本执行时间过长而导致的TimeoutException。
  4. 错误处理: 在JavaScript脚本中加入.catch()块是非常重要的,这样即使fetch请求失败或响应处理出错,Python也能接收到错误信息,而不是脚本挂起或抛出未捕获的异常。
  5. 跨域请求 (CORS): 如果fetch请求的目标URL与当前页面的源不同,可能会遇到CORS问题。确保服务器端已正确配置CORS策略以允许这些请求。

总结

通过execute_async_script方法,Selenium为我们提供了一个强大的机制,可以在浏览器环境中执行异步JavaScript代码,特别是像fetch这样的网络请求。这使得我们能够灵活地发送带有自定义HTTP头的GET或POST请求,并无缝地将异步响应数据检索到Python程序中进行进一步处理。理解其工作原理和注意事项,将有助于更高效地利用Selenium解决复杂的Web自动化任务。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

422

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

537

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

313

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

77

2025.09.10

chrome什么意思
chrome什么意思

chrome是浏览器的意思,由Google开发的网络浏览器,它在2008年首次发布,并迅速成为全球最受欢迎的浏览器之一。本专题为大家提供chrome相关的文章、下载、课程内容,供大家免费下载体验。

864

2023.08.11

chrome无法加载插件怎么办
chrome无法加载插件怎么办

chrome无法加载插件可以通过检查插件是否已正确安装、禁用和启用插件、清除插件缓存、更新浏览器和插件、检查网络连接和尝试在隐身模式下加载插件方法解决。更多关于chrome相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

752

2023.11.06

数据类型有哪几种
数据类型有哪几种

数据类型有整型、浮点型、字符型、字符串型、布尔型、数组、结构体和枚举等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

310

2023.10.31

php数据类型
php数据类型

本专题整合了php数据类型相关内容,阅读专题下面的文章了解更多详细内容。

222

2025.10.31

go语言 注释编码
go语言 注释编码

本专题整合了go语言注释、注释规范等等内容,阅读专题下面的文章了解更多详细内容。

30

2026.01.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 4.5万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 2.6万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号