标题: [文本处理] [已解决]批处理如何遍历网页文件夹ID并输出至文本? [打印本页]
作者: lonron 时间: 2023-5-4 19:04 标题: [已解决]批处理如何遍历网页文件夹ID并输出至文本?
https://189.ly93.cc/api.php?c=list&shareCode=VVFnmuRviQRj&accessCode=? 是某网盘根文件夹里的数据,只需提取 isFolder 和 fileId 参数的值。
进入子文件夹的方式:当 “isFolder” 为 true 时,表示 fileId 值是子文件夹ID。(格式:https://189.ly93.cc/api.php?c=list&shareCode=VVFnmuRviQRj&accessCode=?&fileId=17位fileId)
以下是一个大概的框架,请问要怎么写才能遍历根文件夹及多级子文件夹,以获取其文件夹的fileId,并输出至文本?
- @echo off
- for /f "delims=" %%a in ('powershell "(irm 'https://189.ly93.cc/api.php?c=list&shareCode=VVFnmuRviQRj&accessCode=?&fileId=').count"') do (
- for /f "eol=F delims=| tokens=1-2" %%b in ('powershell "(irm 'https://189.ly93.cc/api.php?c=list&limit=%%a&shareCode=VVFnmuRviQRj&accessCode=?&fileId=').data | %% {'{0}|{1}' -f $_.isfolder,$_.fileid}"') do (
- echo %%c>>test.txt
- )
- )
- pause
复制代码
作者: jyswjjgdwtdtj 时间: 2023-5-4 19:29
搞不懂你为什么要在bat里调用ps?既然有json那直接用js啊?js也有可以get post的com组件可以用啊
作者: lonron 时间: 2023-5-4 19:39
回复 2# jyswjjgdwtdtj
原来用的就是纯bat的方式,要不是for不能支持一行8000多个字符,我根本不想用PS
主要还是完全不会js,一丁点都不会,憋都憋不出一句话。。。
而且我是拿实例学bat的过程中,只是这次刚好遇到的是json罢了。
作者: czjt1234 时间: 2023-5-4 19:57
回复 3# lonron
纯bat能干啥?必须调用外部命令啊
attrib.exe
net.exe
arp.exe
等等windows自带的外部命令
还有众多的第三方命令
curl.exe
gwak.exe
那为啥不能调用
powershell.exe
cscript.exe
作者: jyswjjgdwtdtj 时间: 2023-5-4 20:01
回复 4# czjt1234
我觉得吧 与其调用来调用去的 不如直接写ps或者js或者vbs
作者: lonron 时间: 2023-5-4 20:01
回复 4# czjt1234
没毛病,我并不反感用第三方命令,只是相对于js,PS我还能看得懂自己能修改,而且在我看来PS实现一些东西可以更简单点。只是原本我用的for取截取json数据有点笨办法的意思。。。不过也是弃之不用了
作者: jyswjjgdwtdtj 时间: 2023-5-4 20:05
本帖最后由 jyswjjgdwtdtj 于 2023-5-4 20:12 编辑
回复 3# lonron
盲写一段(没测试过)- var http=new ActiveXObject("msxml2.xmlhttp");
- http.Open("GET","https://189.ly93.cc/api.php?c=list&shareCode=3UBZ3ei6NJJz&accessCode=?",False)
- http.Send()
- var result=eval(http.ResponseText)
复制代码
大小写不熟悉 可能大小写上会出错
然后就- WScript.Echo(result.data[0].fileId)
复制代码
输出72373164319523966
#-_-#莫名不能用……估计是json里有啥不兼容jscript的地方吧
还是去用ps好
作者: lonron 时间: 2023-5-4 20:18
回复 7# jyswjjgdwtdtj
用PS是没问题的,主要是我现在不知道用bat该怎么写才能达到遍历所有子文件夹ID,然后给curl批量下载。获取这个网页数据的原理我都摸索出来了,我要的数据我都有,但就是不会写循环,好痛苦!!!
作者: jyswjjgdwtdtj 时间: 2023-5-4 20:47
回复 8# lonron
那你为啥要用bat呢?直接用ps不成?( ̄_ ̄|||)
作者: jyswjjgdwtdtj 时间: 2023-5-4 20:59
- set dom=createobject("htmlfile")
- set http=createobject("msxml2.xmlhttp")
- http.open "GET","https://189.ly93.cc/api.php?c=list&shareCode=3UBZ3ei6NJJz&accessCode=?",false
- http.send()
- dom.parentwindow.execscript("var j="&http.responsetext)
- set json=dom.parentwindow.j
复制代码
这个json就是js对象 你可以使用它来干啥啥
作者: buyiyang 时间: 2023-5-4 22:15
本帖最后由 buyiyang 于 2023-5-4 22:19 编辑
给一个循环的例子- @echo off
- if "%~1"=="" (
- set "url=https://189.ly93.cc/api.php?c=list&limit=10&shareCode=3UBZ3ei6NJJz&accessCode=?") else (
- set "url=%~1"
- )
- setlocal enabledelayedexpansion
- for /f "delims=" %%a in ('powershell "(irm '%url%').path | %% {'{0}' -f $_.fileName}"') do (
- timeout /t 1 /nobreak
- for /f "eol=0 delims=| tokens=1-3" %%b in ('powershell "(irm '%url%').data | %% {'{0}|{1}|{2}|{3}' -f $_.fileSize,$_.fileId,$_.fileName,$_.isFolder}"') do (
- if "%%e"=="true" (
- set "url=%url%&fileId=%%c"
- call "%~0" "!url!"
- ) else (
- curl
- )
- timeout /t 1 /nobreak
- )
- )
- pause
复制代码
作者: pd1 时间: 2023-5-5 00:14
当“isFolder”参数为true时表示子文件夹ID、为false时表示文件ID。
我是没理解两种情况你要怎么分开处理?
分别怎么处理要给出来
作者: lonron 时间: 2023-5-5 08:22
回复 12# pd1
他们的实际应用关系就是红色加粗部分的:
父(子)文件夹ID都是以第一个网页最后面加&fileId=xxxx呈现的。(可以理解为类似本地情况下,进入某个文件夹。)
文件ID就是在要下载的时候要用,在curl后面的下载地址里面呈现的。
作者: idwma 时间: 2023-5-5 10:34
- #@&cls&powershell "type '%~0'|out-string|iex"&pause&exit
- $global:a='https://189.ly93.cc/api.php?c=list&shareCode=3UBZ3ei6NJJz&accessCode=?'
- $global:b='https://189.ly93.cc/3UBZ3ei6NJJz/{0}?accessCode=?'
- function test($id){
- irm ($global:a+'&fileId='+$id)|%{
- $path=($_.path|%{$_.fileName}) -join '\'
- md $path
- $_.data|%{
- if($_.isFolder){test($_.fileId)}else{
- curl --ssl-no-revoke -Lo ($path+'\'+$_.fileName) ($global:b -f $_.fileId)
- }
- }
- }
- }
- test
复制代码
作者: idwma 时间: 2023-5-8 14:18
- #@&cls&powershell "type '%~0'|out-string|iex"&pause&exit
- $global:a='https://189.ly93.cc/api.php?c=list&shareCode=VVFnmuRviQRj&accessCode=?'
- $global:b='https://189.ly93.cc/VVFnmuRviQRj/{0}?accessCode=?'
- function test($id){
- irm ($global:a+'&fileId='+$id)|%{
- $_.data|%{
- if($_.isFolder){$_.fileId;test($_.fileId)}
- }
- }
- }
- test|sc test.txt
复制代码
作者: lonron 时间: 2023-5-8 18:26
回复 15# idwma
是我要的效果,非常感谢,另外问下,是否有纯P的方法?
作者: czjt1234 时间: 2023-5-8 18:34
回复 15# idwma
这个牛叉了,我试了用vbs,写了好几十行,没高兴写下去
作者: idwma 时间: 2023-5-8 18:58
回复 16# lonron
是不是像一楼的放到bat的for里- @echo off
- for /f "delims=" %%a in ('powershell "function test($id){(irm ('https://189.ly93.cc/api.php?c=list&shareCode=VVFnmuRviQRj&accessCode=?'+'&fileId='+$id)).data|%%{if($_.isFolder){$_.fileId;test($_.fileId)}}};test"') do (
- echo %%a>>test.txt
- )
- pause
复制代码
作者: idwma 时间: 2023-5-8 19:00
回复 17# czjt1234
看前辈们用过递归刚好练习一下
作者: lonron 时间: 2023-5-8 19:21
回复 18# idwma
万分感谢,终于解决了,纠结了我好几天了 T_T,我光改问题说明想让大家看清楚,就改了好几次。
作者: czjt1234 时间: 2023-5-8 19:39
回复 20# lonron
据说程序员最怕的就是改需求
作者: lonron 时间: 2023-5-8 19:43
回复 21# czjt1234
隔行如隔山啊,同样是脚本语言,对PS和P实在很吃力,有的问题用pascal就容易多了
作者: lonron 时间: 2023-5-8 21:02
本帖最后由 lonron 于 2023-5-8 22:11 编辑
回复 18# idwma
老师,不好意思,刚刚认真测试代码后发现有三个问题被我忽略了。还恳请您再次帮忙修改下,谢谢:
1、是需要在遍历的开始就先输出一行根目录ID。(根目录ID在path字段里可以获取,但是子文件夹path字段里的feliId是包括自身以及所有上级目录ID数据的,就是目录树。)
2、是这个页面有一个条数限制,默认是30条数据。(格式是在 c=list 后面加上 &limit= 条数,count 字段是当前目录的文件和文件夹总数。)
3、是这个网站好像对抓取数据有做过载保护,所以需要每次获取一条ID后延迟一秒。(测试过一秒一条基本安全没出现过报错。)
作者: idwma 时间: 2023-5-8 22:59
回复 23# lonron - @echo off
- for /f "delims=" %%a in ('powershell "function test($id){irm ('https://189.ly93.cc/api.php?c=list&limit=99999999999&shareCode=VVFnmuRviQRj&accessCode=?'+'&fileId='+$id)|%%{if(!$global:a){($global:a=$_.path.fileId)}$_.data|%%{if($_.isFolder){$_.fileId;sleep -m 500;test($_.fileId)}}}};test"') do (
- echo %%a>>test.txt
- )
- pause
复制代码
作者: lonron 时间: 2023-5-8 23:04
回复 24# idwma
这个limit能获取实际的数吗?
作者: idwma 时间: 2023-5-8 23:10
回复 25# lonron
可以但要套一层循环
现在这样不好吗可以少发一次网络请求
作者: lonron 时间: 2023-5-8 23:16
回复 26# idwma
条数这个我确实一开始也这么想的,不过我本来就是拿实例学习的,如果老师您方便,还希望您能帮我修改下,真的非常感谢!
作者: idwma 时间: 2023-5-8 23:36
- @echo off
- for /f "delims=" %%a in ('powershell "function test($id){$z=irm ('https://189.ly93.cc/api.php?c=list&shareCode=VVFnmuRviQRj&accessCode=?'+'&fileId='+$id);$z='https://189.ly93.cc/api.php?c=list&limit='+$z.count+'&shareCode=VVFnmuRviQRj&accessCode=?'+'&fileId='+$id;sleep 1;irm $z|%%{if(!$global:a){($global:a=$_.path.fileId)}$_.data|%%{if($_.isFolder){$_.fileId;sleep -m 500;test($_.fileId)}}}};test"') do (
- echo %%a>>test.txt
- )
- pause
复制代码
作者: lonron 时间: 2023-5-8 23:48
回复 28# idwma
非常感谢!!!最后有一个小小的疑问,就是单独把ps这段放入控制台的时候,我发现第一条和第二条是同时出现的,其他都是按固定的延迟显示出来,还有就是抓取ID中途我ctrl+c终止,重新运行这段代码时,根目录的ID不会读取了这是为什么?
作者: idwma 时间: 2023-5-9 14:32
一二条在同一个页面
重置变量$a- powershell "$a=0;function test($id){$z=irm ('https://189.ly93.cc/api.php?c=list&shareCode=VVFnmuRviQRj&accessCode=?'+'&fileId='+$id);$z='https://189.ly93.cc/api.php?c=list&limit='+$z.count+'&shareCode=VVFnmuRviQRj&accessCode=?'+'&fileId='+$id;sleep 1;irm $z|%%{if(!$global:a){($global:a=$_.path.fileId)}$_.data|%%{if($_.isFolder){sleep -m 500;$_.fileId;test($_.fileId)}}}};test"
复制代码
作者: lonron 时间: 2023-5-17 23:58
本帖最后由 lonron 于 2023-5-18 09:44 编辑
回复 30# idwma
https://189.ly93.cc/api.php?c=list&code=7n6r22uae6Jn&pwd=r6sf
老师,麻烦您再帮我看下,由于这个网页的api更新了,path字段里现在变成没有fileid和filename字段了,而是直接用实际id配对实际name这种格式,这种情况要怎么获取根id呢?另外,path里的(子)文件夹名称又要怎样写才能全部获取出来?
powershell "$a=0;function test($id){$z=irm ('https://189.ly93.cc/api.php?c=list&code=7n6r22uae6Jn&pwd=r6sf'+'&id='+$id);$z='https://189.ly93.cc/api.php?c=list&limit='+$z.count+'&code=7n6r22uae6Jn&pwd=r6sf'+'&id='+$id;sleep 1;irm $z|%%{if(!$global:a){($global:a=$_.path.fileId)}$_.data|%%{if($_.isdir){sleep -m 500;$_.id;test($_.id)}}}};test"
作者: idwma 时间: 2023-5-18 17:22
回复 31# lonron - $a=0;
- function test($id){
- $y='https://189.ly93.cc/api.php?c=list&code=7n6r22uae6Jn&pwd=r6sf&fileId=';
- $z=irm ($y+$id);
- if($z.count -gt 30){sleep 1;$z=irm ($y+$id+'&limit='+$z.count)}
- $z|%{
- if(!$global:a){($global:a=$_.path.psobject.properties.name)}
- sleep 1;
- $_.data|%{if($_.isdir){$_.id;test($_.id)}}
- }
- }
- test
复制代码
作者: lonron 时间: 2023-5-18 19:18
回复 32# idwma
有点看懵了,似乎是比原来代码多加了一个前置判断总条数是否大于30?
作者: idwma 时间: 2023-5-18 21:30
回复 33# lonron
前面的不用管把原来的改成第7行一样的就行了
全部获取是要全部显示出来吗
$_.path.psobject.name 是id
$_.path.psobject.value 是文件夹名称
path对象类型变了,可以看下帮助https://learn.microsoft.com/zh-c ... bout-pscustomobject
作者: lonron 时间: 2023-5-20 12:31
本帖最后由 lonron 于 2023-5-20 12:35 编辑
回复 32# idwma
老师,网站所有者跟我说,直接用count赋值给limit的这种方式不可取,会让他的服务器有一定的风险,可能会存在瞬时post或get过多数据的情况。所以他建议我limit应该固定在100以内,然后用&page=的方式来分流获取数据。这貌似涉及到循环了,还请您再帮忙修改下源代码,实在不好意思一直劳烦您,真的非常感谢!
作者: idwma 时间: 2023-5-20 14:52
回复 35# lonron - $a=0;
- function test($id){
- $limit=100;
- $y='https://189.ly93.cc/api.php?c=list&code=7n6r22uae6Jn&pwd=r6sf&fileId=';
- $z=irm ($y+$id+'&limit='+$limit);
- $b=$z.count;
- $c={
- z|%{
- if(!$global:a){($global:a=$_.path.psobject.properties.name)}
- sleep 1;
- $_.data|%{if($_.isdir){$_.id;test($_.id)}}
- }
- }
- if($b -le 100){&$c}else{
- &$c;
- for($($i=1;$b+=100);($b-=$limit) -gt 0;++$i){
- sleep 1;
- $z=irm ($y+$id+'&limit='+$lilmit+'&page='+$i);
- &$c
- }
- }
- }
- test
复制代码
作者: lonron 时间: 2023-5-20 15:25
回复 36# idwma
测试了下第102个开始出现部分重复了,https://189.ly93.cc/file/list?code=QBBzaevemUbm&pwd=4d0d&id=&limit=100 这是用来测试的数据您看下,然后path字段又被他修改回原来了,所以还是用原来的path.id就可以了。
作者: idwma 时间: 2023-5-20 16:30
回复 37# lonron - $a=0;
- function test($id){
- $limit=100;
- $y='https://189.ly93.cc/file/list?code=QBBzaevemUbm&pwd=4d0d&id=';
- $z=irm ($y+$id+'&limit='+$limit);
- $b=$z.count;
- $c={
- $z|%{
- if(!$global:a){($global:a=$_.path.id)}
- sleep 1;
- $_.data|%{if($_.isdir){$_.id;test($_.id)}}
- }
- }
- if($b -le 100){&$c}else{
- &$c;
- for($($i=2;$b+=100);($b-=$limit) -gt 0;++$i){
- sleep 1;
- $z=irm ($y+$id+'&limit='+$lilmit+'&page='+$i);
- &$c
- }
- }
- }
- test
复制代码
作者: lonron 时间: 2023-5-20 19:01
回复 38# idwma
还是重复的,和刚才那个区别 $i 一个是1 一个是2
作者: idwma 时间: 2023-5-20 20:32
回复 39# lonron
18行改成这样- $z=irm ($y+$id+'&limit='+$limit+'&page='+$i);
复制代码
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |