上一主题 下一主题
ScriptCat,新一代的脚本管理器脚本站,与全世界分享你的用户脚本油猴脚本开发指南教程目录
12下一页
返回列表 发新帖

想咨询一个ElementGetter.js元素定位的问题

[复制链接]
  • TA的每日心情
    开心
    2023-7-13 09:56
  • 签到天数: 2 天

    [LV.1]初来乍到

    9

    主题

    93

    回帖

    120

    积分

    中级工程师

    积分
    120

    油中2周年油中3周年

    发表于 2023-8-3 02:04:20 | 显示全部楼层 | 阅读模式
    悬赏1油猫币已解决

    本帖最后由 xiaooooooo 于 2023-8-3 09:48 编辑

    想请教一下各位大佬,我下面两种方法都失败了,但是我调试部分可以成功拿到元素,问题是出在哪里?
    调试链接:https://www.jetstar.com/cn/zh/home?adults=1&children=0&destination=SYD&flexible=1&flight-type=1&infants=0&origin=MEL&selected-departure-date=09-08-2023&tab=1

    // ==UserScript==
    // @match https://booking.jetstar.com/cn/zh/booking/*
    // @icon https://www.google.com/s2/favicons?sz=64&domain=jetstar.com
    // @require http://cdn.bootcss.com/jquery/1.11.2/jquery.js
    // @require https://scriptcat.org/lib/513/2.0.0/ElementGetter.js
    // @grant GM_xmlhttpRequest
    // ==/UserScript==

    (function() {
    'use strict';

    ————————调试部分————————
    elmGetter.selector($);
    elmGetter.selector('css');
    const wenzi = document.querySelector("div.display-currency-AUD > div:nth-child(3) > div.columns > div.js-fare-row > div.js-fare-row-summary > div.flight-card-itinerary > div.flight-card-itinerary-row > div:nth-child(1) > div.js-departure-time")
    elmGetter.each('*', wenzi, el => {
    console.log(el.cloneNode(true));
    console.log($(wenzi).text());//这个就是我想要得到的结果
    });
    ————————调试部分结束————————
    ————————方法一:想从上往下找子元素————————

    elmGetter.each('div.display-currency-AUD div.row', company_name => {
    
        console.info('page is fully loaded');
        var dataList = [];
        for (var i=2; i<company_name.length; i++){
            var shijian = $(company_name[i]).find('div.columns div.js-fare-row div.js-fare-row-summary div.flight-card-itinerary div.flight-card-itinerary-row').eq(0).find('div.js-departure-time').text()
            dataList.push({
                'shijian': shijian
            })
    
        }
        console.info(dataList);
    });

    ————————方法一结束————————
    ————————方法二:想从子元素自己找父级————————

    elmGetter.each('div.row', column1 => {
        const company_name = column1.parent();
        console.info('page is fully loaded');
        var dataList = [];
        for (var i=2; i<company_name.length; i++){
            var shijian = $(company_name[i]).find('div.columns div.js-fare-row div.js-fare-row-summary div.flight-card-itinerary div.flight-card-itinerary-row').eq(0).find('div.js-departure-time').text()
            dataList.push({
                'shijian': shijian
            })
    
        }
        console.info(dataList);
    });

    ————————方法二结束————————

    })();

    最佳答案

    查看完整内容

    each不是获取整个列表给你遍历,而是每获取一项触发一次回调,相当于本身就有遍历效果,由于列表项很可能不是同步加载的,所以是每加载一个触发一次。对于单独一个的节点,你再怎么想遍历他也只有一个呀,可以观察你控制台的输出,是不是每次数组里都只有一项? 如果是想获取特定项,可以在选择器里加nth-child(如你所说,这种情况用get更好),或者在each的回调里用if判断,或者说你只是不想要第一项,那选择器可以这样写::no ...
  • TA的每日心情
    慵懒
    2022-3-8 11:41
  • 签到天数: 2 天

    [LV.1]初来乍到

    22

    主题

    881

    回帖

    1379

    积分

    荣誉开发者

    积分
    1379

    荣誉开发者卓越贡献油中2周年生态建设者油中3周年挑战者 lv2

    发表于 2023-8-3 02:04:21 | 显示全部楼层
    xiaooooooo 发表于 2023-8-3 23:21
    css选择器的用法的确是我理解错了 但是这里我想要弄个数组遍历的想法我觉得是有必要的 因为每一个机票的 ...

    each不是获取整个列表给你遍历,而是每获取一项触发一次回调,相当于本身就有遍历效果,由于列表项很可能不是同步加载的,所以是每加载一个触发一次。对于单独一个的节点,你再怎么想遍历他也只有一个呀,可以观察你控制台的输出,是不是每次数组里都只有一项?
    如果是想获取特定项,可以在选择器里加nth-child(如你所说,这种情况用get更好),或者在each的回调里用if判断,或者说你只是不想要第一项,那选择器可以这样写::not(:nth-child(1))
    回复

    使用道具 举报

  • TA的每日心情
    开心
    3 小时前
  • 签到天数: 213 天

    [LV.7]常住居民III

    305

    主题

    4188

    回帖

    4055

    积分

    管理员

    积分
    4055

    管理员荣誉开发者油中2周年生态建设者喜迎中秋油中3周年挑战者 lv2

    发表于 2023-8-3 09:40:21 | 显示全部楼层

    调试时看看是不是top窗口:

    image.png

    猜想又是因为iframe导致的

    上不慕古,下不肖俗。为疏为懒,不敢为狂。为拙为愚,不敢为恶。
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2023-7-13 09:56
  • 签到天数: 2 天

    [LV.1]初来乍到

    9

    主题

    93

    回帖

    120

    积分

    中级工程师

    积分
    120

    油中2周年油中3周年

    发表于 2023-8-3 09:46:38 | 显示全部楼层
    王一之 发表于 2023-8-3 09:40
    [md]调试时看看是不是top窗口:

    ![image.png](data/attachment/forum/202308/03/094010k2us2xuzakckc27u.p ...

    没太明白 这个top窗口是代表啥?
    回复

    使用道具 举报

  • TA的每日心情
    开心
    3 小时前
  • 签到天数: 213 天

    [LV.7]常住居民III

    305

    主题

    4188

    回帖

    4055

    积分

    管理员

    积分
    4055

    管理员荣誉开发者油中2周年生态建设者喜迎中秋油中3周年挑战者 lv2

    发表于 2023-8-3 09:50:46 | 显示全部楼层
    xiaooooooo 发表于 2023-8-3 09:46
    没太明白 这个top窗口是代表啥?

    最顶层窗口,也就是你访问地址的窗口

    里面可能还有iframe,是其它url,不能直接访问到

    [油猴开发指南]关于脚本如何处理iframe的碎碎念
    https://bbs.tampermonkey.net.cn/thread-2895-1-1.html
    (出处: 油猴中文网)


    [油猴脚本开发指南]基本油猴编程的一些常见误区
    https://bbs.tampermonkey.net.cn/thread-835-1-1.html
    (出处: 油猴中文网)


    可以看看这个
    上不慕古,下不肖俗。为疏为懒,不敢为狂。为拙为愚,不敢为恶。
    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    2022-3-8 11:41
  • 签到天数: 2 天

    [LV.1]初来乍到

    22

    主题

    881

    回帖

    1379

    积分

    荣誉开发者

    积分
    1379

    荣誉开发者卓越贡献油中2周年生态建设者油中3周年挑战者 lv2

    发表于 2023-8-3 22:47:53 | 显示全部楼层
    你这个代码问题太大了,我之前跟你说过each每次只返回一个结果,所以没有必要对company_name进行遍历,但你每次都弄个数组还要遍历他干嘛呢?之前没出错是因为jQuery节点不管结果几个都会放到一个数组结构里,但这次你用了css选择器(切换选择器必须放在each前面,而不是代码最前面),遍历原生的元素节点当然会出问题了。对于css选择器,如果你希望用jQuery语法来处理,用一个$()包裹下就完事了:
    1. elmGetter.selector('css');
    2. elmGetter.each('...', company_name => {
    3.     $(company_name).find(...);
    4. });
    复制代码

    对于jQuery选择器,直接处理就行了,不要搞数组遍历这些多余的操作:
    1. elmGetter.selector($);
    2. elmGetter.each('...', company_name => {
    3.     company_name.find(...);
    4. });
    复制代码

    还有你这个i=2也是个槽点,结果只有1个,下标怎么可能从2开始呢?如果想过滤某些结果,应该直接写if,控制台看到的多个输出并不是你遍历出来的,而是each多次触发的结果,希望你能理解这一点。

    吐槽一句,我当初写这个库就是为了尽可能地简化操作,但你又把他加回去了
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2023-7-13 09:56
  • 签到天数: 2 天

    [LV.1]初来乍到

    9

    主题

    93

    回帖

    120

    积分

    中级工程师

    积分
    120

    油中2周年油中3周年

    发表于 2023-8-3 23:18:50 | 显示全部楼层

    cxxjackie 发表于 2023-8-3 22:47

    你这个代码问题太大了,我之前跟你说过each每次只返回一个结果,所以没有必要对company_name进行遍历,但你 ...

    谢谢大佬指点 选择i=2是因为我要从第二个div.row开始选起,如下图:
    1.png

    回复

    使用道具 举报

  • TA的每日心情
    开心
    2023-7-13 09:56
  • 签到天数: 2 天

    [LV.1]初来乍到

    9

    主题

    93

    回帖

    120

    积分

    中级工程师

    积分
    120

    油中2周年油中3周年

    发表于 2023-8-3 23:21:48 | 显示全部楼层
    cxxjackie 发表于 2023-8-3 22:47
    你这个代码问题太大了,我之前跟你说过each每次只返回一个结果,所以没有必要对company_name进行遍历,但你 ...

    css选择器的用法的确是我理解错了 但是这里我想要弄个数组遍历的想法我觉得是有必要的 因为每一个机票的信息储存在一个div.row的元素下 我想要获取每一个机票的时间路线价格 如果是只需要返回一组结果的话我就用get方法不用each了

    https://www.jetstar.com/cn/zh/ho ... 9-08-2023&tab=1
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2023-7-13 09:56
  • 签到天数: 2 天

    [LV.1]初来乍到

    9

    主题

    93

    回帖

    120

    积分

    中级工程师

    积分
    120

    油中2周年油中3周年

    发表于 2023-8-4 00:28:25 | 显示全部楼层
    本帖最后由 xiaooooooo 于 2023-8-4 00:31 编辑
    cxxjackie 发表于 2023-8-3 23:48each不是获取整个列表给你遍历,而是每获取一项触发一次回调,相当于本身就有遍历效果,由于列表项很可能 ...

    谢谢大佬指点。我根据您的建议修正了代码 但是有个奇怪的地方是 为什么有的时候能获取到机票价格,有的时候又不行呢?测试链接:https://www.jetstar.com/cn/zh/ho ... te=09-08-2023&tab=1
    1.png
    // ==UserScript==
    // @name         jetstar机票获取
    // @namespace    http://tampermonkey.net/
    // @version      0.1
    // @description  try to take over the world!
    // @author       You
    // @match        https://booking.jetstar.com/cn/zh/booking/*
    // @icon         https://www.google.com/s2/favicons?sz=64&domain=jetstar.com
    // @require      http://cdn.bootcss.com/jquery/1.11.2/jquery.js
    // @require      https://scriptcat.org/lib/513/2.0.0/ElementGetter.js
    // @grant        GM_xmlhttpRequest
    // ==/UserScript==

    (function() {
        'use strict';

    // ————————调试部分————————

        elmGetter.selector('css');
        const wenzi = document.querySelector("div.display-currency-AUD > div:nth-child(3) > div.columns > div.js-fare-row > div.js-fare-row-summary > div.flight-card-itinerary > div.flight-card-itinerary-row > div:nth-child(1) > div.js-departure-time")
        elmGetter.each('*', wenzi, el => {
            console.log(el.cloneNode(true));
            console.log($(wenzi).text());//这个就是我想要得到的结果
        });
    // ————————调试部分结束————————
        elmGetter.selector($);
        elmGetter.each('div.display-currency-AUD div.row', company_name => {
          
            console.info('page is fully loaded');
            var dataList = [];
            var chufashijian = company_name.find('div.flight-card-itinerary-row div:nth-child(1)').find('div.itinerary-info__time ').text();
            var chufajichang = company_name.find('div.flight-card-itinerary-row div:nth-child(1)').find('div.itinerary-info__airport').text();
            var daodashijian = company_name.find('div.flight-card-itinerary-row div:nth-child(3)').find('div.itinerary-info__time ').text();
            var daodajichang = company_name.find('div.flight-card-itinerary-row div:nth-child(3)').find('div.itinerary-info__airport').text();
            var xingchengshijian = company_name.find('strong.travelduration').text();
            var price = company_name.find('div.pricepoint span.pricepoint__middle').text();
            if (chufashijian){
                dataList.push({
                    'chufashijian': chufashijian,
                    'chufajichang': chufajichang,
                    'daodashijian': daodashijian,
                    'daodajichang': daodajichang,
                    'xingchengshijian': xingchengshijian,
                    'price': price
                })



            console.info(dataList);
            }
                
        });

    })();
    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    2024-10-28 07:07
  • 签到天数: 193 天

    [LV.7]常住居民III

    712

    主题

    5959

    回帖

    6758

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    6758

    荣誉开发者喜迎中秋油中2周年生态建设者

    发表于 2023-8-4 00:48:02 | 显示全部楼层
    xiaooooooo 发表于 2023-8-4 00:28
    谢谢大佬指点。我根据您的建议修正了代码 但是有个奇怪的地方是 为什么有的时候能获取到机票价格,有的时 ...

    css写的不对,有一部分找到了隐藏div身上,可以再精确一下路径

    以下为问题无关建议

    1.代码尽量贴到脚本站发私密,然后按版本号贴给大家,这样可读性会好很多

    2.变量风格可以参考一下其他人的找一个适合自己的,目前命名风格有一定的杂乱

    3.css路径是一键复制的吧,可以参考论坛指南和其他人文章学一下,机器生成出来的对其他人几乎是不可读的,有一点为难其他开发者

    4.大部分问题和调试方案指南都有,多通读指南各类文章

    5.学会基本的调试,断点,条件断点,Dom断点,具备基本的调试能力

    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
    回复

    使用道具 举报

    发表回复

    本版积分规则

    快速回复 返回顶部 返回列表