标题: 【练习-071】批处理或VBS获取论坛首页指定数据 [打印本页]
作者: batman 时间: 2013-1-13 15:11 标题: 【练习-071】批处理或VBS获取论坛首页指定数据
本帖最后由 batman 于 2013-1-14 12:31 编辑
出题目的:
1、体现批处理和VBS脚本的实用性
2、加深对正则的理解
解题要求:
1、因纯批处理不能实现读取网页的功能,因此可使用三方工具,但不能在批中调用VBS(使用MSHTA解释器除外)
2、VBS中不可调用BAT
加分原则:
满分30分,思路为重,视情况加分
题目如下:
用VBS或BAT读取论坛首页www.bathome.net源代码中最新主题、最新回复、热门主题的所有帖子信息,并以下面的形式输出到TXT文本
作者: 冷玉公子 时间: 2013-1-14 00:34
老大 格式也不行哦 太长了 继续努力中
纯P的,目前搞定最后一部分,下一步处理拿到那三个信息
纯P的不可能有正则吧,除非依赖第三方。拿这个真的很蛋疼啊。
--------------------相当华丽的分割线------------------------------------
2013-01-14 日更新
先上图
[attach]6050[/attach]
--------------------相当华丽的分割线------------------------------------
利用Curl获取首页数据,然后剩下的就是纯P内部函数搞定。
个人觉得代码绝对有可以优化的地方,只可惜水平不高,还请高手指正。
PS:怎么版主老是没几句好话给我啊,哎。。。。。。- @Echo Off&SetLocal EnableDelayedExpansion
- Mode Con Cols=130 Lines=20
- Title 批处理获取论坛首页指定数据 『冷玉公子』
-
- Set "Index=index.php"
- Set "Url=http://www.bathome.net/index.php"
- If Exist %Index% Del /f /q %Index%
-
- Echo 正在更新首页信息,请稍后。
- Curl -# -G -o %Index% %Url%
-
- For /F "tokens=*" %%A In (index.php) Do (
- Set tStr="%%A"
- IF !e1Switch! == True Set e1Switch=False&Call :_TitleResovle !tStr! 最新主题&Pause>Nul
- IF !e2Switch! == True Set e2Switch=False&Call :_TitleResovle !tStr! 最新回复&Pause>Nul
- IF !e3Switch! == True Set e3Switch=False&Call :_TitleResovle !tStr! 热门主题&Pause>Nul
- Set e1Str=!tStr:homegrids_c_1=DandyMu!
- Set e2Str=!tStr:homegrids_c_2=DandyMu!
- Set e3Str=!tStr:homegrids_c_3=DandyMu!
- IF Not !e1Str! == !tStr! Set e1Switch=True
- IF Not !e2Str! == !tStr! Set e2Switch=True
- IF Not !e3Str! == !tStr! Set e3Switch=True
- )
-
- Goto :Eof
-
- :_TitleResovle
- Set trStr=%1
- For /F "usebackq tokens=*" %%A In ('%trStr%') Do (
- @Rem Echo %%A
- Call :_LiResolve %%A %2
- )
- Goto :Eof
-
- ::Rem %1带处理的Li标签内容 %2标题
- :_LiResolve
- Cls
- Echo [%2]
- Echo=
- Echo ---------------------------------------------------------------------------------------------------------------------------------
- Set Str=%1
- For /F "usebackq tokens=*" %%A In ('%Str%') Do (
- Set Html="%%A"&Set Code=!Html:^</li^>=^</li^>;!
- For /F "tokens=1-8 delims=;" %%1 In ("!Code!") Do (
- Call :_EchoInfo "%%1"&Call :_EchoInfo "%%2"&Call :_EchoInfo "%%3"&Call :_EchoInfo "%%4"
- Call :_EchoInfo "%%5"&Call :_EchoInfo "%%6"&Call :_EchoInfo "%%7"&Call :_EchoInfo "%%8"
- )
- )
- Goto :Eof
-
- :_EchoInfo
- For /F "usebackq tokens=1-20 delims=><=" %%A In ('%1') Do (
- For /F "tokens=1 delims='" %%1 In ("%%K") Do Set "HTURL=http://www.bathome.net/%%1"
- Set "HTID=%%G"&Set "HTTITLE=%%M"
- IF "!HTTITLE:~1,5!" == "color" Set "HTTITLE=%%N"
- Echo 主题:!HTTITLE! 发帖ID:!HTID! URL:!HTURL!
- Echo ---------------------------------------------------------------------------------------------------------------------------------
- )
- Goto :Eof
复制代码
作者: batman 时间: 2013-1-14 00:48
本帖最后由 batman 于 2013-1-14 00:51 编辑
回复 2# 冷玉公子
请仔细阅读上面的说明,我没说用纯批吧,而且纯批也是有正则的,虽然findstr那么弱。。。
作者: QIAOXINGXING 时间: 2013-1-14 12:43
本帖最后由 QIAOXINGXING 于 2013-1-14 17:17 编辑
曾经提问过类似问题:http://www.bathome.net/thread-15638-1-1.html- @echo off&SetLocal EnableDelayEdexpansion&cd /d "%~dp0"
- Mode Con Cols=130 Lines=30
- del /f index.html>nul 2>nul
- wget http://www.bathome.net 1>nul 2>nul
- for /f "delims=" %%a in (index.html) do (
- set "STR=%%a"
- if defined flag (
- echo 【!cont!】
- call :tiqu "%%a"
- set "flag="
- )
- for %%b in (最新主题 最新回复 热门主题) do (
- if "!STR!" neq "!STR:%%b=!" set "flag=1"&set "cont=%%b"
- )
- )
- pause&exit
- :tiqu
- for %%b in ("%~1") do set "str=!str!%%b"
- set "str=!str:'= !"
- set "str=!str:<= !"
- for %%b in (!str!) do (
- set "s=%%b"
- if "%%~xb" == ".html" (
- set "Url=http://www.bathome.net/%%b"
- set "flag1=1"
- )
- if "!s:~0,1!" equ ">" (
- set "t=!s:~1!"
- rem 发现下3句写成 "if not defined flag1 set "Id=!t!" else ("会出错,有时flag1为空时也会显示。
- if not defined flag1 (
- set "Id=!t!"
- ) else (
- set "Title=!t!"
- set "flag1="
- echo 主题:!Title! 发帖ID:!Id! URL:!Url!
- )
- )
- )
- goto :eof
复制代码
作者: apang 时间: 2013-1-14 15:38
本帖最后由 apang 于 2013-1-14 21:48 编辑
- Set ie = CreateObject("InternetExplorer.Application")
- ie.Navigate "http://www.bathome.net"
- ie.Visible = False
- Do While ie.Busy Or ie.ReadyState <> 4 :Wscript.Sleep 100 :Loop
- Text = ie.Document.Body.InnerHtml :ie.Quit
- Pattern1 = """>(.*?)</A>.*href=""(thread.*)"">(.*)</A>"
- Pattern2 = "id=homegrids_t_[1-3]>(?:(最新主题|最新回复|热门主题))"
-
- Set Re = New RegExp
- Re.Pattern = Pattern1 & "|" & Pattern2
- Re.Global = True
- Re.IgnoreCase = True
- For Each a in Re.Execute(Text)
- Set FSO=CreateObject("Scripting.FilesystemObject")
- Str = "[" & a.SubMatches(3) & "]"
- if Str = "[]" Then
- Str = "主题:" & a.SubMatches(2) & " "
- Str = Str & "发贴ID:" & a.SubMatches(0) & " " & "URL:"
- Str = Str & "http://www.bathome.net/" & a.SubMatches(1)
- End If
- FSO.OpenTextFile("Result.txt",8,True).WriteLine Str
- Set FSO = Nothing
- Next
-
- CreateObject("Wscript.Shell").Run "NotePad Result.txt"
复制代码
作者: batman 时间: 2013-1-14 16:23
回复 5# apang
兄弟是故意每个版块只取第一个帖子信息的吗?不过分析了你的代码应该是你split方法的局限所导致的。。。
作者: batman 时间: 2013-1-14 16:31
希望大家多用用正则来解决这类提取数据的问题
作者: apang 时间: 2013-1-14 20:38
回复 6# batman
老大,不是我故意的,是理解题意错了。。。
修改了,这次不知怎样。
作者: 冷玉公子 时间: 2013-1-14 20:50
回复 7# batman
老大,4楼那哥们的是有问题的吧。
还有啊,老大给个批处理用正则的例子吧,难道要用 Sed 或者 Awk?
作者: batman 时间: 2013-1-14 23:49
回复 8# apang
分已加上,正则用得很好,只是能不用IE就Perfect了,IE你懂的。。。
作者: batman 时间: 2013-1-14 23:51
本帖最后由 batman 于 2013-1-14 23:56 编辑
回复 9# 冷玉公子
我一没curl二没wget(个人不喜欢用三方),所以没测试你们的代码,我是看你们的代码加的分。。。
批中findstr支持正则啊
作者: Batcher 时间: 2013-1-15 00:12
回复 9# 冷玉公子
http://www.bathome.net/thread-24-1-1.html
作者: batman 时间: 2013-1-15 00:40
本人的解:- Dim objXML, Url
- Url = "http://www.bathome.net"
- Set objXML = CreateObject("MSXML2.XmlHttp")
- objXML.open "GET", Url, False
- objXML.send()
- Do Until objXML.readyState = 4 : WScript.Sleep 200 : Loop
- Dim objADODB
- Set objADODB = CreateObject("Adodb.Stream")
- objADODB.Type = 1
- objADODB.Mode = 3
- objADODB.Open()
- objADODB.Write objXML.responseBody
- Set objXML = Nothing
- Dim objFSO, Temp
- Set objFSO = CreateObject("Scripting.FileSystemObject")
- Temp = objFSO.GetSpecialFolder(2) & "\"
- objADODB.SaveToFile Temp & "bathome.html", 2
- Set objADODB = Nothing
- Dim objHTML, objIH
- Set objHTML = GetObject(Temp & "bathome.html", "HtmlFile")
- Do Until objHTML.ReadyState = "complete" : WScript.Sleep 200 : Loop
- Dim A, B, objStr
- A = Array("最新主题", "最新回复", "热门主题")
- B = Array("发帖ID:", "最新回复ID:", "最新回复ID:")
- For i = 1 To 3
- objIH = objHTML.GetElementByID("homegrids_c_" & i).InnerHtml
- objStr = objStr & "["& A(i - 1) & "]" & vbCrLf & GetInfo(objIH, B(i - 1)) & vbCrLf
- Next
- Set objHTML = Nothing
- objFSO.DeleteFile Temp & "bathome.html"
- objStr = Replace(objStr, "<UL class=textinfolist>" & vbCrLf, "")
- objFSO.OpenTextFile("HomePage.txt", 2, True).Write Replace(objStr, vbLf, vbCrLf)
- Set objFSO = Nothing
- CreateObject("Wscript.Shell").Run "cmd /chomepage.txt", True, False
-
- Function GetInfo(Str1, Str2)
- Dim objRE, Matches, Matche
- Set objRE = New RegExp
- objRE.Global = True
- objRE.IgnoreCase = True
- objRE.Pattern = ".*?"">(.*?)</a.*?(\d{1,}-\d{1,}-\d{1,}).*?"">(.*?)</a.*"
- GetInfo = objRE.Replace(Str1, "主题:$3 " & Str2 & "$1 URL:" & Url & "/thread-$2.html")
- Set objRE = Nothing
- End Function
复制代码
作者: bluewing009 时间: 2013-1-15 00:51
本帖最后由 bluewing009 于 2013-1-15 00:58 编辑
一问:
bat既然无法实现网页的下载,那么我借用vbs实现可否?
vbs只是下载网页~
这样就与你“但不能在批中调用VBS”冲突了......
对要求1 不解》。。。
作者: batman 时间: 2013-1-15 01:17
本帖最后由 batman 于 2013-1-15 01:19 编辑
回复 14# bluewing009
一答:
我摆明了就是不让你用批处理echo神功大*法(这也屏蔽),怎么着?咬我?
作者: bluewing009 时间: 2013-1-15 11:23
回复 15# batman
牙口不好...估计咬不动....
同样是第三方, 我用exe也是下载 用vbs也是下载....
都是把网页下载成txt么....
然后再处理~ 这个和出题目的不相悖吧....
作者: terse 时间: 2013-1-16 14:40
额 恶补- set ie = createobject("internetexplorer.application")
- ie.visible = false
- ie.navigate "http://www.bathome.net"
- do until ie.readystate = 4
- wscript.sleep 200
- loop
- Set FSO=CreateObject("Scripting.FilesystemObject")
- DIM N,S,var
- for i = 0 to 47 step 2
- N = i \ 16
- if i MOD 16 = 0 Then
- var = var & "[" & ie.document.getElementById("homegrids_t_" & N + 1).outerText & "]" & vbcr & vblf
- End If
- if N <> 0 Then
- Str = "主题:" & ie.document.links(i+28).innertext & " " & "最新回复:"
- ELSE Str = "主题:" & ie.document.links(i+28).innertext & " " &"发帖ID:"
- End If
- var= var & str & ie.document.links(i+27).outerText & " " & "URL:" & ie.document.links(i+28).href & vbcr & vblf
- Next
- FSO.OpenTextFile("Rult.txt",2,True).WriteLine var
- ie.quit
- Set ie = Nothing
复制代码
作者: terse 时间: 2013-1-19 14:36
搞个三方的 练手 SED 还是有点生疏- @ECHO OFF
- set url="http://bbs.bathome.net/"
- set s1=最新主题&set "s2=热门主题|最新回复"
- set "s=s/<[^\/]*'>([^\/]*)<[^']*'([^']*)'[^<]*'>([^<]*)<\/a><\/li>"
- curl -s "%URL%"|sed -r -n "/%s1%|%s2%/!d;s/<[^<]*>//g;s/\r|\n//;s/^/[/;s/$/]/;N;/%s1%/%s%/主题:\3\t发帖ID:\1\tURL: %URL:/=\/%\2\n/g;/%s2%/%s%/主题:\3\t最新回复:\1\tURL:%URL:/=\/%\2\n/g;p" >Rult.txt
- pause
复制代码
作者: tmplinshi 时间: 2013-1-19 15:36
本帖最后由 tmplinshi 于 2013-1-19 16:01 编辑
- curl bathome.net | sed -n -r "s|^.*homegrids_t_[123]\x22>([^\n\r<]+).*$|[\1]|p; s|(<li>[^?]+\?)(uid[^>]+>)|\1发帖ID:|g; s|(<li>[^?]+\?)(username[^>]+>)|\1最新回复:|g; s|<li>[^?]+\?([^<]+)[^']+'([^']+)'[^']+'([^']+)[^<]+</a></li>|主题:\3 \1 URL:http://bathome.net/\2\n|gp" >bathome.txt
复制代码
作者: terse 时间: 2013-1-19 16:23
tmplinshi 发表于 2013-1-19 15:36
抛个砖 引来版主之玉 研究下 SED 正则
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |