jjzjj

javascript - 有没有办法用 HtmlUnit 触发滚动事件,或者根本不可能?

coder 2024-07-16 原文

我目前正在学习 HtmlUnit 以抓取网站。一切都进行得很顺利,直到我遇到一个动态页面(例如,我正在使用 Pinterest 网站),当用户向下滚动时,该页面上的元素会动态添加。

我已经尝试了几种应该在真实浏览器中触发滚动的方法(我将在下面展示)。 在继续之前,我想提一下我已经设置了以下配置:

    webclient.setJavaScriptEnabled(true);
    webclient.setAjaxController(new NicelyResynchronizingAjaxController());

假设我想让我所有的关注者都在 Pinterest 上。我导航到那个页面,现在因为第一次只有 24 个,我想向下滚动,触发对服务器的 Ajax 调用并检索下一组关注者的事件。

1) 纯 javascript 或 jQuery 代码触发窗口滚动。

    ScriptResult sr = followersPage.executeJavaScript("window.scrollBy(0,1000)");
    // One version in jQuery
    // ScriptResult sr = followersPage.executeJavaScript("$(window).scrollTop(0,1000);");
    // also tried with the body, html, with animation
    // ScriptResult sr = followersPage.executeJavaScript("$("html, body").animate({ scrollTop: $(document).height() }, 1000);");
    webclient.waitForBackgroundJavaScript(10000);
    followersPage = (HtmlPage)sr.getNewPage();

=> 当我检查到顶部的距离时,它等于 0,结果页面与原始页面相同。在Eclipse中调试时,当我跨过执行javascript的那一行时,它直接进入下一行,没有任何延迟。如果我编写任何其他 javascript,例如:

     ScriptResult sr = followersPage.executeJavaScript("$(div.GridItems).html('new content')");

您会注意到调试器在该行挂起半秒,这意味着 javascript 已执行。

2) 将焦点从一个跟随者 anchor 更改为另一个(我选择 anchor 是因为当您单击 TAB 键时它用于焦点顺序):

    HtmlDivision gridItems = followersPage.getFirstByXPath("//div[contains(concat(' ',@class,' '),' GridItems ')]");
    List<HtmlDivision> els = (List<HtmlDivision>) gridItems.getByXPath("//div[@class='item ']");
    List<HtmlDivision> items = (List<HtmlDivision>) gridItems.getByXPath("//div[@class='item ']");
    for (HtmlDivision item : items) {
        HtmlAnchor a = item.getFirstByXPath("//a[@class='userWrapper']");
        a.focus();
        webClient.waitForBackgroundJavaScript(1000);
    }
    followersPage = (HtmlPage) webClient.getCurrentWindow().getEnclosedPage();

同样,没有发生滚动。结果页面和原来一样

3) 创建一个触发窗口滚动事件的按钮:

    HtmlButton scrollButton = (HtmlButton) followersPage.createElement("button");
    scrollButton.setAttribute("type", "button");
    scrollButton.setAttribute("onclick", "window.scrollTo(0,document.body.scrollHeight);");
    gridItems.appendChild(scrollButton);
    followersPage = scrollButton.click();

不幸的是,它没有用。

我尝试了很多其他方法,但直到现在都没有积极的结果。

我阅读了很多有关该主题的相关文章,也在 stackoverflow 上。而且似乎没有人设法使用 HtmlUnit 使滚动工作,因为大多数问题仍未得到解答。这就是为什么我想知道该功能是否曾经起作用。

有人设法滚动页面(简单页面,没有 ajax)吗? 有人设法滚动页面,触发一些 ajax 调用的事件吗?

最佳答案

我建议你使用 casperjs在这种情况下,我尝试使用 htmlunit 而不是 使用htmlunit打开pinterest并得到了

runtimeError: message=[Property 0 not found.] sourceName=[https://s.pinimg.com/webapp/js/vendor-react-d20f99c48b5d58e4821c.js] line=[1] lineSource=[ null] lineOffset=[0]

所以看起来htmlunit对js没有很好的支持,即使是最新的2.31..

这是一个使用 casperjs 的演示代码:

var utils = require('utils')
var fs = require('fs')
var system = require('system')

var casper = require('casper').create({
    verbose: true,
    logLevel: 'debug',
    localToRemoteUrlAccessEnabled: true,
    webSecurityEnabled: false,
    plainTextAllContent: false,
    viewportSize: {
        width: 1440,
        height: 800
    },
    onError: function(casper, msg, backtrace) {
        utils.dump(backtrace)
    }
});

var cookie = fs.read('cookie.txt').trim() 

casper.on('started', function() {

    this.page.onError = function(msg, trace) {
        casper.echo('Error => ' + msg + '\nError trace => ')
        utils.dump(trace)
    }

    this.page.customHeaders = {
        "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36",
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
        "Accept-Language": "zh-CN,en;q=0.5",
        "Accept-Encoding": "gzip, deflate",
        "Connection": "keep-alive",
        "Pragma": "no-cache",
        "Cookie": cookie
    }


});

casper.start('https://www.pinterest.com', function() {

    this.then(function() {
        this.waitForSelector('div[class="_wx _2h"]', function() {
            this.echo("waitForSelector 'div[class=_wx _2h]' is done")
            this.scrollTo(0, 1000);
            this.wait(5000, function() {
                this.scrollTo(0, 2000);
            })
        })

    })

});

将上面的代码保存到名为demo.js的文件中,然后使用以下命令启动casperjs

casperjs --engine=slimerjs demo.js

然后您将看到 firefox 浏览器启动并正常运行!

关于javascript - 有没有办法用 HtmlUnit 触发滚动事件,或者根本不可能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23491638/

有关javascript - 有没有办法用 HtmlUnit 触发滚动事件,或者根本不可能?的更多相关文章

  1. ruby - 如何以所有可能的方式将字符串拆分为长度最多为 3 的连续子字符串? - 2

    我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123

  2. ruby-on-rails - 有没有办法为 CarrierWave/Fog 设置上传进度指示器? - 2

    我在Rails应用程序中使用CarrierWave/Fog将视频上传到AmazonS3。有没有办法判断上传的进度,让我可以显示上传进度如何? 最佳答案 CarrierWave和Fog本身没有这种功能;你需要一个前端uploader来显示进度。当我不得不解决这个问题时,我使用了jQueryfileupload因为我的堆栈中已经有jQuery。甚至还有apostonCarrierWaveintegration因此您只需按照那里的说明操作即可获得适用于您的应用的进度条。 关于ruby-on-r

  3. ruby-on-rails - 事件管理员日期过滤器日期格式自定义 - 2

    是否有简单的方法来更改默认ISO格式(yyyy-mm-dd)的ActiveAdmin日期过滤器显示格式? 最佳答案 您可以像这样为日期选择器提供额外的选项,而不是覆盖js:=f.input:my_date,as::datepicker,datepicker_options:{dateFormat:"mm/dd/yy"} 关于ruby-on-rails-事件管理员日期过滤器日期格式自定义,我们在StackOverflow上找到一个类似的问题: https://s

  4. ruby-on-rails - 事件记录 : Select max of limit - 2

    我正在尝试将以下SQL查询转换为ActiveRecord,它正在融化我的大脑。deletefromtablewhereid有什么想法吗?我想做的是限制表中的行数。所以,我想删除少于最近10个条目的所有内容。编辑:通过结合以下几个答案找到了解决方案。Temperature.where('id这给我留下了最新的10个条目。 最佳答案 从您的SQL来看,您似乎想要从表中删除前10条记录。我相信到目前为止的大多数答案都会如此。这里有两个额外的选择:基于MurifoX的版本:Table.where(:id=>Table.order(:id).

  5. ruby - 有没有办法从 ruby​​ case 语句中访问表达式? - 2

    我想从then子句中访问c​​ase语句表达式,即food="cheese"casefoodwhen"dip"then"carrotsticks"when"cheese"then"#{expr}crackers"else"mayo"end在这种情况下,expr是食物的当前值(value)。在这种情况下,我知道,我可以简单地访问变量food,但是在某些情况下,该值可能无法再访问(array.shift等)。除了将expr移出到局部变量然后访问它之外,是否有直接访问caseexpr值的方法?罗亚附注我知道这个具体示例很简单,只是一个示例场景。 最佳答案

  6. ruby-on-rails - 有没有一种工具可以在编码时自动保存对文件的增量更改? - 2

    我最喜欢的Google文档功能之一是它会在我工作时不断自动保存我的文档版本。这意味着即使我在进行关键更改之前忘记在某个点进行保存,也很有可能会自动创建一个保存点。至少,我可以将文档恢复到错误更改之前的状态,并从该点继续工作。对于在MacOS(或UNIX)上运行的Ruby编码器,是否有具有等效功能的工具?例如,一个工具会每隔几分钟自动将Gitcheckin我的本地存储库以获取我正在处理的文件。也许我有点偏执,但这点小保险可以让我在日常工作中安心。 最佳答案 虚拟机有些人可能讨厌我对此的回应,但我在编码时经常使用VIM,它具有自动保存功

  7. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

  8. ruby-on-rails - 事件管理员和自定义方法 - 2

    这是我在ActiveAdmin中的自定义页面ActiveAdmin.register_page"Settings"doaction_itemdolink_to('Importprojects','settings/importprojects')endcontentdopara"Text"endcontrollerdodefimportprojectssystem"rakedataspider:import_projects_ninja"para"OK"endendend我想做的是,当我单击“导入项目”按钮时,我想在Controller中执行rake任务。但是我无法访问该方法。可能是什

  9. python - python中有没有类似于ruby的||=的表达式 - 2

    我在Ruby中遇到了一个有趣的表达式:a||="new"表示如果没有定义a,则将"new"值赋给a;否则,a将保持原样。在进行一些数据库查询时很有用。如果设置了该值,我不想触发另一个数据库查询。所以我在Python中尝试了类似的思路:a=aifaisnotNoneelse"new"失败了。我认为这是因为如果未定义a,则无法在Python中执行“a=a”。所以我能得出的解决方案是检查locals()和globals(),或者使用try...except表达式:myVar=myVarif'myVar'inlocals()and'myVar'inglobals()else"new"或try:

  10. ruby-on-rails - 在不重新查询数据库的情况下重新排序 Rails 中的事件记录? - 2

    例如,假设我有一个名为Products的模型,并且在ProductsController中,我有以下代码用于product_listView以显示已排序的产品。@products=Product.order(params[:order_by])让我们想象一下,在product_listView中,用户可以使用下拉菜单按价格、评级、重量等进行排序。数据库中的产品不会经常更改。我很难理解的是,每次用户选择新的order_by过滤器时,rails是否必须查询,或者rails是否能够以某种方式缓存事件记录以在服务器端重新排序?有没有一种方法可以编写它,以便在用户排序时rails不会重新查询结果

随机推荐