selenium捞取http请求信息

UI自动化过程中,经常存在需要获取http请求信息的场景。
例如:元素文案为接口返回需要,需要验证文案正确性;出现报错时方便排查问题,打印http请求日志等

方式一:selenium-wire

selenium-wire官网 该库仅支持python3.6+

# 以获取API商城 - IP查询服务的timestamp签名为例
# 是seleniumwire 不是 selenium
import time
from seleniumwire import webdriver
driver = webdriver.Chrome()

driver.get('https://apis.baidu.com/store/aladdin/land?cardType=ipSearch')
driver.find_element_by_xpath('//*[@id="app"]/div[2]/div/div/div[2]/input').send_keys("112.10.36.59")
driver.find_element_by_xpath('//*[@id="app"]/div[2]/div/div/div[2]/div').click()
time.sleep(1)
# Access requests via the `requests` attribute
for request in driver.requests:
    if request.response and "timestamp" in request.headers:
        print(request.headers["timestamp"])

driver.close()

方式二:设置代理

浏览器设置代理,从代理服务器获取请求,该方式不做详细描述
设置代理
推荐代理工具使用Mitmproxy

方式三:捞取webdrive日志

启动浏览器时添加如下信息

from selenium.webdriver.common.desired_capabilities import DesiredCapabilities

option = webdriver.ChromeOptions()
option.add_experimental_option('perfLoggingPrefs', {'enableNetwork': True})
caps = DesiredCapabilities.CHROME
caps['goog:loggingPrefs'] = {'performance': 'ALL'}
driver = webdriver.Chrome(chrome_driver_path, options=option, desired_capabilities=caps)
"""
日志的类型
['Network.loadingFailed', 'Network.loadingFinished', 'Network.resourceChangedPriority',
 'Network.requestServedFromCache', 'Network.requestWillBeSent', 'Network.requestWillBeSentExtraInfo',
 'Network.responseReceived', 'Network.responseReceivedExtraInfo', 'Network.dataReceived',
 'Page.frameAttached', 'Page.frameRequestedNavigation', 'Page.frameStoppedLoading',
 'Page.frameClearedScheduledNavigation', 'Page.loadEventFired', 'Page.frameStartedLoading',
 'Page.frameDetached', 'Page.frameScheduledNavigation', 'Page.frameNavigated', 'Page.frameResized',
 'Page.domContentEventFired']
请求的类型(待补充)
 [XHR(接口请求), Fetch(接口请求), 'Script'(.js), 'Stylesheet(.css)', 'Image'(.png等), 'Font', 'Document(文件), 'Manifest', 'Ping', 'Preflight', 'Navigation', 'other']
"""

time.sleep(2)  # 等待一下大部分请求处理完成
request_list = []  # 所有的请求
response_list = []  # 所有的返回
cache_list = []  # 所有的缓存读取记录
for responseReceived in self.driver.get_log('performance'):
    message = json.loads(responseReceived['message'])['message']
    # 获取所有请求信息(请求信息集中在requestWillBeSent)
    if message['method'] == 'Network.requestWillBeSent':
        request_id = message['params']['requestId']
        request = message['params']['request']
        try:  # 尝试获取请求body,type为浏览器开发者模式network下类型筛选(用于区分接口请求和页面请求)
            request_list.append({'id': request_id, 'type': message['params']['type'],
                                 'url': request['url'], 'method': request['method'],
                                 'req_time': responseReceived['timestamp'], 'req_headers': request['headers'],
                                 'req_body': json.loads(request['postData'])})
        except:
            request_list.append({'id': request_id, 'type': message['params']['type'],
                                 'url': request['url'], 'method': request['method'],
                                 'req_time': responseReceived['timestamp'], 'req_headers': request['headers']})
    # 获取所有返回信息(返回信息集中在responseReceived,但是其中无body信息)
    elif message['method'] == 'Network.responseReceived':
        request_id = message['params']['requestId']
        response = message['params']['response']
        try:  # responseReceived日志中无response body信息,需要额外进行获取
            resp_body = json.loads(self.driver.execute_cdp_cmd('Network.getResponseBody', {'requestId': request_id})['body'])
        except:
            resp_body = None
        try:  # 能获取到requestHeaders尽量使用,因为此处比较全
            response_list.append({'id': request_id, 'type': message['params']['type'], 'url': response['url'],
                                  'resp_time': responseReceived['timestamp'],
                                  'req_headers': response['requestHeaders'], 'resp_status': response['status'],
                                  'resp_headers': response['headers'], 'resp_body': resp_body})
        except:
            response_list.append({'id': request_id,  'type': message['params']['type'], 'url': response['url'],
                                  'resp_time': responseReceived['timestamp'], 'resp_status': response['status'],
                                  'resp_headers': response['headers'], 'resp_body': resp_body})
    # 获取是否为缓存请求(从浏览器缓存直接获取,一般为css、js文件请求)
    elif message['method'] == 'Network.requestServedFromCache':
        request_id = message['params']['requestId']
        cache_list.append({'id': request_id})
# 合并request与cache(cache必定少于等于request)
new_request_list = []
for request in request_list:
    num = 0
    for cache in cache_list:
        num += 1
        if request['id'] == cache['id']:
            new_request_list.append(dict(request, **{'req_from_cache': True}))
            break
        if num == len(cache_list) and request['id'] != cache['id']:
            new_request_list.append(dict(request, **{'req_from_cache': False}))
# 合并request与response(response必定少于等于request,原因是拉取日志的时候会有一些还没收到response的请求)
complete_request_list = []  # 完整有response的请求列表
incomplete_request_list = []  # 不完整没有response的请求列表
for request in new_request_list:
    num = 0
    for response in response_list:
        num += 1
        if request['url'] == response['url'] and request['id'] == response['id'] and request['type'] == response['type']:
            complete_request_list.append(dict(request, **response))  # response在后,因为response中的req_headers比较全
            break
        if num == len(response_list) and request['id'] != response['id']:
            incomplete_request_list.append(request)
  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Selenium是一个用于自动化测试的工具,主要用于模拟用户在浏览器上的操作。它虽然可以发送HTTP请求,但并不是其主要功能,通常不推荐直接使用Selenium来发送HTTP请求Selenium主要用于模拟用户在浏览器上的行为,如点击、输入等操作。它可以打开一个浏览器窗口,加载指定的URL,并执行一系列操作,检查页面元素的状态和结果。这对于Web应用程序的自动化测试非常有用。 如果你只是想发送HTTP请求,可以选择其他更适合的工具,如Python中的requests库。requests库提供了简单而强大的API,可以方便地发送各种类型的HTTP请求,并获取响应结果。它支持常见的HTTP方法,如GET、POST等,也支持设置请求头、传递参数等功能,非常适合发送HTTP请求。 使用requests库发送HTTP请求的示例代码如下: ``` import requests url = "http://example.com" response = requests.get(url) print(response.status_code) print(response.text) ``` 上述代码首先使用requests库引入了需要的模块,然后定义了要发送请求的URL。接着,使用`requests.get()`方法发送了一个GET请求,并将结果保存在response对象中。最后,我们可以通过`response.status_code`获取响应状态码,通过`response.text`获取响应内容。 总结来说,Selenium虽然可以发送HTTP请求,但并不是其主要功能所在。如果你只是想发送HTTP请求,建议使用更合适的工具如requests库。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值