将 requests.Session() cookie 传输到 Python 中的 selenium Web 驱动程序

Posted

技术标签:

【中文标题】将 requests.Session() cookie 传输到 Python 中的 selenium Web 驱动程序【英文标题】:Transferring requests.Session() cookies to a selenium web driver in Python 【发布时间】:2016-08-02 08:43:25 【问题描述】:

在研究和修补之后,我似乎不知道我可以尝试什么。我基本上想在这里做这个问题的反面:Is it possible to "transfer" a session between selenium.webdriver and requests.session

我想“点击”网页上的 javascript 按钮,我通过会话中的一系列 GET/POST 请求“到达”(重要的是,自从我的 GET/POST 以来,cookie 得到维护和无缝传输请求位于需要登录用户的页面上)。

但是,经过一番谷歌搜索后,我发现 requests 似乎没有提供类似的东西。我找到了 selenium,并且一直在尝试正确传输 cookie(不成功)。

import requests, requests.utils, lxml.html
from lxml.cssselect import CSSSelector
from selenium import webdriver

# urls which requests will be made to
login_url = 'login-url-here'
logged_in_data_url = 'logged-in-data-here'

# create my Session to contain my cookies
with requests.Session() as s:
    login_html = s.get(login_url)
    tree = lxml.html.fromstring(login_html.text)
    important_key1 = list(set(tree.xpath('//*[@id="fm1"]/div/div[3]/input[1]/@value')))[0]
    important_key2 = list(set(tree.xpath('//*[@id="fm1"]/div/div[3]/input[2]/@value')))[0]
    form_value = "submit"

    login_payload = 
        'post-field-1': 'post-data-1',
        'post-field-2': 'post-data-2',
        'important_key1': 'important_value1',
        'important_key2': 'important_value2',
        'important_key3': 'important_value3'
    

    login_result = s.post(login_url,
                    data=login_payload,
                    headers = dict(referer=login_url))

    logged_in_data_html = s.get(logged_in_data_url)
    tree = lxml.html.fromstring(logged_in_data_html.text)
    print(logged_in_data_html.text)

    # Attempt at transferring cookies, currently fails
    cookie_dict = requests.utils.dict_from_cookiejar(s.cookies)
    driver = webdriver.Firefox()
    for cookie in cookie_dict:
        driver.add_cookie(cookie)

    driver.get(logged_in_data_url)

    # prints same contents as login_html.text,
    # meaning cookie transfer failed and the session was thrown out
    print(driver.page_source) 

关于从这里做什么的任何建议或指示?

编辑:我对selenium-requests的尝试:

import seleniumrequests
import lxml.html
from lxml.cssselect import CSSSelector

# urls which requests will be made to
login_url = 'login-url-here'
logged_in_data_url = 'logged-in-data-here'

driver = seleniumrequests.Firefox()

login_html = driver.request('GET', login_url)
tree = lxml.html.fromstring(login_html.text)
important_key1 = list(set(tree.xpath('//*[@id="fm1"]/div/div[3]/input[1]/@value')))[0]
important_key2 = list(set(tree.xpath('//*[@id="fm1"]/div/div[3]/input[2]/@value')))[0]
form_value = "submit"

# following print statements print value1, value2 respec
print ("important_key1 = " + important_key1)
print("important_key2 = " + important_key2)

login_payload = 
    'post-field-1': 'post-data-1',
    'post-field-2': 'post-data-2',
    'important_key1': 'important_value1',
    'important_key2': 'important_value2',
    'important_key3': 'important_value3'


login_result = driver.request('POST', login_url,
                              data=login_payload,
                              headers = dict(referer=login_url))

# this should print out the landing page after being logged in
# source code contains important_key1, 2, and 3 with different values
# the GET and POST requests seem to be in different sessions
# how do I fix that?
print(login_result.text)

【问题讨论】:

【参考方案1】:

我不相信本地可以做到这一点。不过,Selenium 有一个扩展名为 selenium-requests,您应该可以使用它。

编辑:

尝试将以下内容添加到您的代码中。阅读源代码后,这应该可以工作(并在 POST 请求期间使用 requests Session 自动初始化。

response = driver.request('GET', logged_in_data_url)

【讨论】:

我确实尝试使用 selenium-requests,但我遇到了一个单独的问题,我将执行以下操作:1)通过 seleniumrequests.Firefox() 创建一个 webdriver; 2) 在 login_url 上发出 GET 请求; 3) 执行 xpath 报废以获取即将到来的 POST 所需的数据; 4) 尝试使用数据发布; 5)从驱动程序读取page_source(它仍然会读取与login_url页面相同的源,这意味着它没有登录。我想我可以再试一次...... 如果您将代码作为 更新 发布到您的原始帖子中,我可能会提供帮助。 对于漫长的等待,我深表歉意——我已将我的尝试/代码添加到原始帖子中(并更具体地(希望)描述了我的 selenium-requests 问题)! 您能详细说明在 POST 请求期间自动初始化的 requests.Session() 吗? POST 请求无法登录,因为“important_key#”的值不正确,因为 GET 和 POST 请求之间没有维护会话。它创建一个 GET 请求,从响应中的源获取“important_key#”,但 POST 请求再次访问先前存储的“important_key#”无效的页面。这是我要纠正的问题,我看不出您的代码如何解决它。感谢您的宝贵时间,非常感谢! 您可能会发现这很有帮助。 :) docs.python-requests.org/en/master/user/advanced

以上是关于将 requests.Session() cookie 传输到 Python 中的 selenium Web 驱动程序的主要内容,如果未能解决你的问题,请参考以下文章

Python 的 Requests 库线程中的 Session 对象是不是安全?

requests接口自动化9-共享session和传递cookie

python接口自动化中requests.session

python中requests.session的妙用

修改requests库session默认连接数

Swift相当于Python的requests.session()?