问题 如何“手动”返回WebBrowser?


我正在研究一个有时需要记住特定页面的Web scraper,然后转到其他页面,然后返回到该页面。目前我只保存页面的网址,但这对Google地图这样的网页不起作用,其中网址始终相同。

我可以看到了 GoBack 方法确实回到了上一页,所以不知怎的 WebBrowser 记得以前的页面是什么。我该如何手动完成此操作?我可以计算自从我想要返回然后调用的页面以来访问了多少页面 GoBack 尽可能多次,但这是非常不可靠和不优雅的。所以我想知道我怎么能实现一个 GoBackToAParticularPage 方法。

我认为有一件事可以让我更接近解决方案:保存所有帧的URL,然后在返回该页面时将它们放回原处。我认为这将解决谷歌地图问题。我还没有测试过它。我不确切知道这样做的正确方法是什么。在设置URL之前,我需要等待帧存在。


861
2018-03-24 05:58


起源



答案:


您可以使用

webBrowser1.Document.Window.History.Go(x);

其中x是一个int,表示浏览器历史记录中的相对位置。

x = -2会导航两页。

更新:更多信息 HtmlHistory.Go()


5
2018-03-28 21:08



出于好奇,在什么情况下这个答案不能正常工作或者它如何不能产生理想的行为?据我所知,它适用于谷歌地图示例。您是否真的希望访问History对象本身的数据? - Yetti
不,我不想计算导航数,因为你怎么知道什么时候导航 DocumentComplete 算作历史中的一个项目?我没有可靠的方法来了解什么 x 应该。当我在那个页面时,我知道我想要回到哪个页面,但是一旦它导航了,我不知道它们之间有多少页面。 - Juan
当浏览器设置为未设置历史记录时会发生什么? - Marshal
@jsoldi嗯,我不用 DocumentComplete 在我的代码中。当我找到“我要回去的页面”(当我按下按钮时)时,我只是保存历史长度。这最终适用于不同帧和诸如此类的不同复杂导航。但是,我不得不承认这一点 是 在非常特殊的情况下不可靠,我相信这对你来说没用。 :( - Yetti
@marshal如果通过将CLng(2)(或数字2)传递到导航方法来取消历史记录,那么您将无法返回该页面,它也会从WB控件历史记录中消失(就像它从不发生了),但是你所遵循的任何链接仍然会有历史信息,因为.navigate历史记录取消仅适用于该导航页面请求。但是,有一些方法可以取消点击链接的历史记录,也可以截取@ BeforeNavigate,取消历史记录并进行重新排序(在任何开始加载之前都会出现renav)。 - Erx_VB.NExT.Coder


答案:


您可以使用

webBrowser1.Document.Window.History.Go(x);

其中x是一个int,表示浏览器历史记录中的相对位置。

x = -2会导航两页。

更新:更多信息 HtmlHistory.Go()


5
2018-03-28 21:08



出于好奇,在什么情况下这个答案不能正常工作或者它如何不能产生理想的行为?据我所知,它适用于谷歌地图示例。您是否真的希望访问History对象本身的数据? - Yetti
不,我不想计算导航数,因为你怎么知道什么时候导航 DocumentComplete 算作历史中的一个项目?我没有可靠的方法来了解什么 x 应该。当我在那个页面时,我知道我想要回到哪个页面,但是一旦它导航了,我不知道它们之间有多少页面。 - Juan
当浏览器设置为未设置历史记录时会发生什么? - Marshal
@jsoldi嗯,我不用 DocumentComplete 在我的代码中。当我找到“我要回去的页面”(当我按下按钮时)时,我只是保存历史长度。这最终适用于不同帧和诸如此类的不同复杂导航。但是,我不得不承认这一点 是 在非常特殊的情况下不可靠,我相信这对你来说没用。 :( - Yetti
@marshal如果通过将CLng(2)(或数字2)传递到导航方法来取消历史记录,那么您将无法返回该页面,它也会从WB控件历史记录中消失(就像它从不发生了),但是你所遵循的任何链接仍然会有历史信息,因为.navigate历史记录取消仅适用于该导航页面请求。但是,有一些方法可以取消点击链接的历史记录,也可以截取@ BeforeNavigate,取消历史记录并进行重新排序(在任何开始加载之前都会出现renav)。 - Erx_VB.NExT.Coder


尝试这个!

的javascript:history.go(-1)”


4
2018-03-24 06:11



我试过了。不可靠。 - Juan
我做的就是得到 history.length 之前和之后再打电话 history.go(before - after)。一团糟。所有这些都注入了JavaScript btw。 - Juan
@jsoldi:你没有必要注入JS来做这件事。该 Document.Window.History.Length C#中的属性应该更好。 - Gabe


我知道已经说了几句话,所以我不会重写它,但是,如果你真的想要使用JavaScript方法(即:如果你想使用javascript历史对象而不是webbrowser控件历史对象)并且想知道如何做到这一点。您可以在.NET WB控件中使用.InvokeScript,或者如果您希望兼容.NET和.NET,则可以使用:

您可以在.NET控件的.NET版本和WB控件的当前/ .NET版本中使用.execScript。您还可以选择要执行的脚本的语言,即:“JScript”或“VBScript”。这是一个班轮:

WebBrowser1.Document.parentWindow.execScript "alert('hello world');", "JScript" 

使用JavaScript历史记录对象的好处是,如果通过将数字“2”发送到.navigate方法中来杀死webbrowser控件中的历史信息,则转到WB控件中取消历史记录的页面将不起作用,但它将在JavaScript的历史对象中工作,这是一个优势。

再次,这只是对这篇文章所讨论的想法的向后兼容补充,包括一些未提及的其他花絮。

让我知道,如果我可以为您提供进一步的帮助,那么答案已被接受。


2
2018-02-11 23:35





通过 javascript Location 对象你可以实现你的任务。

<FORM><INPUT TYPE="BUTTON" VALUE="Go Back" 
ONCLICK="history.go(-1)"></FORM>

还检查

JavaScript历史对象

对于历史信息


1
2018-03-24 06:09



这有效但它意味着计算导航,这是我想要避免的。 - Juan
@jsoldi - 我认为你需要检查历史对象的文档..但我认为它不允许你回去而不计算导航 - Pranay Rana


根据设计,浏览器历史是不透明的;否则会打开一个安全漏洞:您真的希望您访问的每个页面都能看到您访问过的页面/网站吗?可能不会。

要做你想做的事,你需要实现自己的URI堆栈,跟踪需要重新访问的内容。


1
2018-03-29 19:34



这就是我的工作,但它在谷歌地图和其他一些地方搞砸了,因为每个页面上的URL都是相同的。但正如我所说,当通过调用WebBrowser的GoBack返回时它确实有效,因此IE除了导航到以前的URL之外还做了其他事情.v并且我想手动做什么。 - Juan
当您通过历史对象返回时它会起作用,因为浏览器也会缓存结果。对于返回的内容发生更改(由于AJAX调用或表单帖子)而URL保持不变的页面,除了URI之外,您可能还需要为该特定URI请求实现自己的内容缓存。 - Nicholas Carey
知道怎么做吗?我实际上尝试保存我想要返回的页面的DocumentText,然后导航到该页面,然后使用保存的文本设置DocumentText,但这会将URL更改为大约空白并弄乱相关链接。我认为您的解决方案可行,但不知道如何实现该缓存系统。 - Juan


你不想用 history.go(-1) 因为它不可靠但是,您无法使用该网址,因为GoogleMaps等网页的网址始终相同。

如果URL相同但内容不同,则表示确定页面内容的值是从URL以外的其他位置提取的。

这可能在哪里?

您最可能的嫌疑人是已发布的表单集合,但数据也可能来自Cookie。

我认为索引绝对位置比相对位置更有意义,因为正如您所指出的,相对位置可能不可靠。问题是您需要获取发送到Web服务器的所有数据,以了解其实际绝对位置(因为URI不够)。

执行此操作的方法是创建页面的本地副本,并使用服务器上的URL替换提交URL(可以是链接,表单或javascript中)。然后,当您单击GoogleMaps页面上的某些内容以触发更改(这似乎不会影响URL)时,您将在服务器上收到该数据,并且能够确定实际位置。

把它想象成一个查询字符串。

如果我有

<form action="http://myhost.com/page.html" method="get">
   <input type="hidden" name="secret_location_parameter" value="mrbigglesworth" />
   <input type="submit" />
</form>

然后我点击提交按钮,我会被带到网址

 http://myhost.com/page.html?secret_location_parameter=mrbigglesworth

但是,如果我有

<form action="http://myhost.com/page.html" method="post">
   <input type="hidden" name="secret_location_parameter" value="mrbigglesworth" />
   <input type="submit" />
</form>

然后我点击提交按钮,然后我被带到网址

 http://myhost.com/page.html

服务器仍然收到 secret_location_parameter=mrbigglesworth,但它将其作为表单值而不是查询字符串值,因此从URL中看不到它。服务器可能会呈现不同的页面,具体取决于 secret_location_parameter 值,但不更改网址,如果使用post方法,则会显示多个网页位于同一网址。

我的观点是,你可能从错误的角度解决问题,因为你不明白幕后发生了什么。我当然在做假设,但根据你提出问题的方式,我认为这可能对你有所帮助


1
2018-04-03 03:58





如果您不需要在视觉上看到最新情况,那么使用WebClient类可能会有更优雅的方式来导航和解析URL,或许详细说明您的特定程序会产生更清晰的结果。


0
2018-04-01 22:25





假设您在表单上有一个webbrowser控件,并且您正在尝试实现返回。

以下是解决方案。 (如果假设错了。请纠正我)

添加webbrowser,文本框,按钮为btnBack

历史变量还具有用于导航的URL数据(但当前未使用)。

C#解决方案

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }
    private void Form1_Load(object sender, EventArgs e)
    {
         WebBrowser1.Url = new Uri("http://maps.google.com");
    }
    Stack< String> History = new Stack<String>();

    private void WebBrowser1_Navigating(object sender, WebBrowserNavigatingEventArgs e)
    {
            TextBox1.Text = e.Url.ToString();
            History.Push(e.Url.ToString());
    }

    private void btnBack_Click(object sender, EventArgs e)
    {
        if(WebBrowser1.CanGoBack) 
        {
            WebBrowser1.GoBack();
        }

    }

}
}

Vb解决方案

Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    WebBrowser1.Url = New Uri("http://maps.google.com")
End Sub

Private Sub WebBrowser1_Navigating(ByVal sender As Object, ByVal e As System.Windows.Forms.WebBrowserNavigatingEventArgs) Handles WebBrowser1.Navigating
    TextBox1.Text = e.Url.ToString
    History.Push(e.Url.ToString)
End Sub
Dim History As New Stack(Of String)
Private Sub btnBack_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnBack.Click
    If WebBrowser1.CanGoBack Then
        WebBrowser1.GoBack()
    End If
End Sub

End Class

0
2018-04-02 08:44





以编程方式将标记元素添加到DOM中,以用于稍后要返回的页面。回溯浏览器历史记录时,请在每个标记后检查该标记 history.go(-1) 当你遇到它时停下来。在某些情况下,这可能证明是不可靠的,在这种情况下,记住深度级别可以作为备用方法。

您可能需要尝试插入元素的正确时间,以确保它已正确记录在历史记录中。


0
2018-04-03 23:40