Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Html 如何以编程方式从命令行检索我的SO代表和徽章数量? 原始问题_Html_Bash_Curl_Terminal_Html Parsing_Xidel - Fatal编程技术网

Html 如何以编程方式从命令行检索我的SO代表和徽章数量? 原始问题

Html 如何以编程方式从命令行检索我的SO代表和徽章数量? 原始问题,html,bash,curl,terminal,html-parsing,xidel,Html,Bash,Curl,Terminal,Html Parsing,Xidel,我最初的尝试是运行curlhttps://stackoverflow.com/users/5825294/enlico 并将结果导入sed/awk。然而,正如我经常读到的,sed和awk并不是解析HTML代码的最佳工具。此外,如果我更改用户名,上面的URL也会更改 哦,这是我对sed的快速尝试,为了可读性,我写了多行: 卷曲https://stackoverflow.com/users/5825294/enlico 2> /dev/null | sed-nE' /头衔=声誉/,/青铜徽章/{ /

我最初的尝试是运行curlhttps://stackoverflow.com/users/5825294/enlico 并将结果导入sed/awk。然而,正如我经常读到的,sed和awk并不是解析HTML代码的最佳工具。此外,如果我更改用户名,上面的URL也会更改

哦,这是我对sed的快速尝试,为了可读性,我写了多行:

卷曲https://stackoverflow.com/users/5825294/enlico 2> /dev/null | sed-nE' /头衔=声誉/,/青铜徽章/{ /名声/{ N N
实现这一点的方法很少;我个人更喜欢将xpath与xidel等工具结合使用,尽管您也可以使用xmlstarlet等

你可以使用

xidel https://stackoverflow.com/users/5825294/enlico  -e "//div[@title='reputation']/div/div[@class='grid--cell fs-title fc-dark']/text()"
同样,金牌数量通过以下方式获得:

xidel https://stackoverflow.com/users/5825294/enlico  -e "//div[@class='grid ai-center s-badge s-badge__gold']//span[@class='grid grid__center fl1']/text()"

在第二个xpath表达式中将字符串gold更改为silver或brown将获得另外两个类别。

使用StackExchange API和jq解析响应的完整示例

!/usr/bin/env bash 此脚本获取并打印一些用户信息 使用stackexchange的API从堆栈站点 将其更改为stackoverflow的数字用户ID 堆栈UID=5825294 STACK_SITE='stackoverflow' 栈https://api.stackexchange.com/2.2' API\u CACHE=~/.CACHE/stack\u API mkdir-p$API_缓存 使用stackexchange API获取堆栈站点用户并缓存结果 @参数: $1:网站示例stackoverflow $2:数字用户ID @输出: &1:API Json回复 堆栈api::用户{ stack_站点=$1 堆栈uid=$2 cache_file=${API_cache}/${stack_site}-users-${stack_uid}.json 昨天\u ref=${API\u CACHE}/dayed.ref touch-d昨天$昨天\u参考 过期缓存 [$cache\u file-ot$dayed\u ref]&&rm-f-$cache\u file 仅当没有缓存的应答时调用堆栈API [-f$cache_file]| | curl\ -沉默的\ -输出$cache\u文件\ -请求获取\ -url${STACK\u API}/users/${STACK\u uid}?site=${STACK\u site} 返回缓存的答案 zcat-force-$cache_文件2>/dev/null } IFS=$'\n'读-r-d用户名声誉青铜银金< 正如我经常读到的,sed和awk不是解析HTML代码的最佳工具

没错。与其重复别人已经说过的话,我想说:看看:

可惜最后一个网站已经过时了,因为要解析HTML源代码,我随时都会选择瑞士刀工具

HTML源 要提取的信息位于第一个节点中:

//a[@href]=https://stackoverflow.com/users/5825294/]也会起作用

然后,获取所需特定信息的最简单方法是选择所有子体标题属性/@title的值:

此外,如果我更改用户名,上面的URL也会更改

如你所见,https://stackoverflow.com/users/5825294 也行

StackExchange API 目前xidel还不支持-H Accept编码:gzip,deflate,但是解析返回的JSON没有问题

$ curl -s --compressed "https://api.stackexchange.com/2.2/users/5825294?site=stackoverflow" | \
  xidel - -se '
    $json/(items)()/(
      join((reputation,"reputation")),
      for $x in reverse(map:keys(badge_counts)) return
      join((map:get(badge_counts,$x),$x,"badges"))
    )
  '
11156 reputation
5 gold badges
27 silver badges
56 bronze badges
古老的智慧是,你呢

卷曲https://stackoverflow.com/users/5825294/enlico -s|php-r'$d=new DOMDocument;@$d->loadHTMLstream\u get_contentsSTDIN;$xp=new domdxpath$d;foreach$xp->query/*[@id=\user card\]//*[contains@title,\badges\]作为$foo{echo$foo->getAttributetitle,PHP_EOL;}echo preg_replace/\\s+/,$xp->query/*[@title=\reputation\]->item0->textContent;' 5枚金徽章 27枚银徽章 56枚青铜徽章 11144声誉

您可以将用户名作为参数或通过环境传递。对于解析,请展示您的尝试,以便我们有一些具体的代码来讨论。请参阅@user1934428,这是具体的代码。@enlico:我看到您已经有了一个很好的答案,并且莱娅·格里斯提供了一个很好的链接。您现在应该已经解决了。。。。青铜徽章的数量错误-API结果的分页{has_more:true}。当您可以轻松解析配置文件页面的html源代码时,为什么还要麻烦使用如此繁琐的方法?如何-e'//span[@class=profile communities rep-badges][1]//@title'?@Reino正如我在回答中所说,有几种方法可以达到目的。提取title属性的属性值是另一种方法。但是,通常我不会依赖位置选择器,即[1],在您的评论中,即使它们有效,因为它们往往像中一样脆弱,位置也更可能随着时间的推移而改变,而不是节点名称或其属性和属性值。这很公平。在这种情况下-e'//a[@title=Stack Overflow]/span[@class=profile communities rep-badges]//@“title”可以作为一行。不需要对3个不同的徽章进行3次查询。@Reino Yes和No;这取决于您的具体目标;如果您希望将3个徽章放在一堆中,则该表达式有效。但是,如果您希望将银徽章的数量具体定为27,则可以查看是否更高或者比别人的银徽章还低
需要使用其他表达式之一的更有针对性的方法。同样,有几种方法可以剥猫皮——这取决于你要对付的猫的类型……OP的帖子中没有任何地方说明能够将输出与其他人的徽章数量进行比较的要求。我知道OP想要他的声誉+一堆徽章,他的sed解决方案正在展示,而我的一行程序正是这样做的。我想我应该发布我自己的答案。我看到银和铜徽章的数量与我看到的不同。我已经核实了银质徽章的数量没有重复,并且我可以检索每个徽章的.award_计数,如果我想获得所显示的数字,则将其汇总;但是你知道为什么铜牌是7吗?我没有49个重复的青铜徽章…哦,关于声誉,我看我可以用jq-r'.items |[0].user.reputation'来获得它。您建议我如何将其集成到您的脚本中?@Enlico修复了徽章的数量,使用了错误的API方法。很好的解释和回答!
$ xidel -s "https://stackoverflow.com/users/5825294" \
        -e '//a[@title="Stack Overflow"]/span[@class="profile-communities--rep-badges"]' --printed-node-format=html
$ xidel -s "https://stackoverflow.com/users/5825294" \
        -e '//a[@title="Stack Overflow"]/span[@class="profile-communities--rep-badges"]//@title'
11,156 reputation
5 gold badges
27 silver badges
56 bronze badges
$ curl -s --compressed "https://api.stackexchange.com/2.2/users/5825294?site=stackoverflow" | \
  xidel - -se '
    $json/(items)()/(
      join((reputation,"reputation")),
      for $x in reverse(map:keys(badge_counts)) return
      join((map:get(badge_counts,$x),$x,"badges"))
    )
  '
11156 reputation
5 gold badges
27 silver badges
56 bronze badges