【问题标题】:Requests.get() function does not give same result as the webbrowser.open() functionRequests.get() 函数给出的结果与 webbrowser.open() 函数不同
【发布时间】:2020-03-02 07:17:40
【问题描述】:

我有一个 url,我需要运行它才能进行刷新。它将刷新数据缓存并在 tableau server 中显示最新上传的数据。网址是这样的:

http://servername/views/workbookname/dashboard1?:refresh=yes

当我使用 webbrowser 库打开 url 时,会执行刷新,但我得到一个打开的浏览器。当我使用请求获取 url 时,它不会刷新并给我一个 200 的响应,我认为这是成功的。

有人知道为什么会这样吗?如何在执行 get 功能时静默使用 webbrowser 库打开 url 并在之后关闭它,或者让请求充当 webbrowser?

import webbrowser
url = 'http://servername/views/workbookname/dashboard1?:refresh=yes'
webbrowser.open(url)

import requests
url = "http://servername/views/workbookname/dashboard1?:refresh=yes"
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.76 Safari/537.36', "Upgrade-Insecure-Requests": "1","DNT": "1","Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8","Accept-Language": "en-US,en;q=0.5","Accept-Encoding": "gzip, deflate"}
html = requests.get(url,headers=headers)
print(html)

【问题讨论】:

  • 您在这里的最终目标是什么?只是为了刷新数据?或者之后做一些工作?如果有,是什么样的工作?根据您的目标,实施可能会完全不同。
  • 尝试使用requests.post 调用来执行请求。
  • @JackTaylor 是的,只是用 ?:refresh=yes 模拟网页的运行
  • @b_c 我试过了,但没用
  • Tableau 社区论坛上的 This post 建议您应该使用 API 直接发出刷新命令,而不是通过代码通过浏览器发出。他们确实有一个 python library 可供您使用(与 JavaScript 不同)。

标签: python python-3.x tableau-api


【解决方案1】:

requests.get() 只是在“GET”请求之后返回从服务器接收到的标记,而无需任何进一步的客户端执行。

而在浏览器上下文中,可以在客户端 javascript 上完成更多工作。我没有专门查看您的页面,但可能有某些 javascript 代码在做进一步处理。

您可以使用 Selenium,而不是 web browserrequests。你可以阅读更多关于它的信息here

Selenium 让您可以像使用浏览器一样浏览页面,但也让您可以灵活地使用 python 代码自动控制页面上的操作。

您也许可以使用Selenium Chrome Webdriver 在后台加载页面。 (或者您可以使用 Firefox 驱动程序)。

转到 chrome://settings/help 检查您当前的 chrome 版本并从 here 下载该版本的驱动程序。确保将驱动程序文件保存在您的 PATH 或您的 python 脚本所在的同一文件夹中。

试试这个:

from selenium.webdriver import Chrome # pip install selenium
from selenium.webdriver.chrome.options import Options

url = "http://servername/views/workbookname/dashboard1?:refresh=yes"

#Make it headless i.e. run in backgroud without opening chrome window
chrome_options = Options()  
chrome_options.add_argument("--headless")

# use Chrome to get page with javascript generated content
with Chrome(executable_path="./chromedriver", options=chrome_options) as browser:
     browser.get(url)
     page_source = browser.page_source

注意

当您打开 URL 时,webbrowser 模块会启动您的默认浏览器,该浏览器已经缓存了您的凭据/cookie。然而,如果您的 URL 需要任何身份验证或登录才能访问,则必须在使用 selenium 获取页面时提供这些。将每个 selenium 网络驱动程序会话视为 incognito 会话。 Here 是一个关于如何使用 Web 驱动程序模拟登录的示例。


参考资料:

selenium - chromedriver executable needs to be in PATH

【讨论】:

  • 我去看看登录
  • 我查看了它返回的 html 标签,是的,它返回了登录页面。当我检查 chrome 中的代码时,我可以看到内部标签,但在返回时(python 中的打印源页面)它不存在?你有没有遇到过这种情况?用户名和密码标签位于输出中缺少的标签内。
  • @JonathanLam,我过去遇到过类似的事情。但就我而言,这是因为登录表单被隐藏了,我需要先单击登录按钮,然后才能看到电子邮件/密码字段。如果您知道这两个字段的 ID,则可以通过执行 javascript 直接设置值。示例:stackoverflow.com/a/58737372/11914067
【解决方案2】:

浏览器打开的原因仅仅是因为 webbrowser.open() 应该这样做,而不是发送 HTTP 请求,而是打开浏览器并输入 URL。一个可能的解决方案是使用 selenium 而不是 webbrowser,因为当我查看它时,我没有找到您正在使用的包的无头选项。所以这里是:

from selenium.webdriver import Chrome
from selenium.webdriver.chrome.options import Options

url = "<URL>"

chrome_options = Options()  
chrome_options.add_argument("--headless")

with Chrome(options=chrome_options) as browser:
     browser.get(url)

如果此解决方案不可接受,因为您需要使用 webdriver 而不是 selenium,您需要找到一种将选项传递给浏览器实例的方法。我没有找到使用 dir() 或 help() 将此参数传递给 webbrowser 的方法,但如果我找到了一些东西,我会添加它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-20
    • 2014-01-30
    • 1970-01-01
    • 2014-05-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多