Board logo

标题: 【练习-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文本
[最新主题]

主题:计算e的值 发帖ID:chineseman2 URL:http://www.bathome.net/thread-21713-1-1.html
..................................................................
[最新回复]

主题:计算e的值 最新回复ID:chineseman2 URL:http://www.bathome.net/thread-21713-1-1.html
..................................................................
[热门主题]

主题:批处理如何删除指定目录下的文件夹? 最新回复ID:terse URL:http://www.bathome.net/thread-21572-1-1.html
..................................................................

作者: 冷玉公子    时间: 2013-1-14 00:34

老大 格式也不行哦 太长了 继续努力中
纯P的,目前搞定最后一部分,下一步处理拿到那三个信息
纯P的不可能有正则吧,除非依赖第三方。拿这个真的很蛋疼啊。
--------------------相当华丽的分割线------------------------------------
2013-01-14 日更新
先上图
[attach]6050[/attach]
--------------------相当华丽的分割线------------------------------------
利用Curl获取首页数据,然后剩下的就是纯P内部函数搞定。
个人觉得代码绝对有可以优化的地方,只可惜水平不高,还请高手指正。
PS:怎么版主老是没几句好话给我啊,哎。。。。。。
  1. @Echo Off&SetLocal EnableDelayedExpansion
  2. Mode Con Cols=130 Lines=20
  3. Title 批处理获取论坛首页指定数据 『冷玉公子』
  4. Set "Index=index.php"
  5. Set "Url=http://www.bathome.net/index.php"
  6. If Exist %Index% Del /f /q %Index%
  7. Echo 正在更新首页信息,请稍后。
  8. Curl -# -G -o %Index% %Url%
  9. For /F "tokens=*" %%A In (index.php) Do (
  10. Set tStr="%%A"
  11. IF !e1Switch! == True Set e1Switch=False&Call :_TitleResovle !tStr! 最新主题&Pause>Nul
  12. IF !e2Switch! == True Set e2Switch=False&Call :_TitleResovle !tStr! 最新回复&Pause>Nul
  13. IF !e3Switch! == True Set e3Switch=False&Call :_TitleResovle !tStr! 热门主题&Pause>Nul
  14. Set e1Str=!tStr:homegrids_c_1=DandyMu!
  15. Set e2Str=!tStr:homegrids_c_2=DandyMu!
  16. Set e3Str=!tStr:homegrids_c_3=DandyMu!
  17. IF Not !e1Str! == !tStr! Set e1Switch=True
  18. IF Not !e2Str! == !tStr! Set e2Switch=True
  19. IF Not !e3Str! == !tStr! Set e3Switch=True
  20. )
  21. Goto :Eof
  22. :_TitleResovle
  23. Set trStr=%1
  24. For /F "usebackq tokens=*" %%A In ('%trStr%') Do (
  25. @Rem Echo %%A
  26. Call :_LiResolve %%A %2
  27. )
  28. Goto :Eof
  29. ::Rem %1带处理的Li标签内容 %2标题
  30. :_LiResolve
  31. Cls
  32. Echo [%2]
  33. Echo=
  34. Echo ---------------------------------------------------------------------------------------------------------------------------------
  35. Set Str=%1
  36. For /F "usebackq tokens=*" %%A In ('%Str%') Do (
  37. Set Html="%%A"&Set Code=!Html:^</li^>=^</li^>;!
  38. For /F "tokens=1-8 delims=;" %%1 In ("!Code!") Do (
  39. Call :_EchoInfo "%%1"&Call :_EchoInfo "%%2"&Call :_EchoInfo "%%3"&Call :_EchoInfo "%%4"
  40. Call :_EchoInfo "%%5"&Call :_EchoInfo "%%6"&Call :_EchoInfo "%%7"&Call :_EchoInfo "%%8"
  41. )
  42. )
  43. Goto :Eof
  44. :_EchoInfo
  45. For /F "usebackq tokens=1-20 delims=><=" %%A In ('%1') Do (
  46. For /F "tokens=1 delims='" %%1 In ("%%K") Do Set "HTURL=http://www.bathome.net/%%1"
  47. Set "HTID=%%G"&Set "HTTITLE=%%M"
  48. IF "!HTTITLE:~1,5!" == "color" Set "HTTITLE=%%N"
  49. Echo 主题:!HTTITLE! 发帖ID:!HTID! URL:!HTURL!
  50. Echo ---------------------------------------------------------------------------------------------------------------------------------
  51. )
  52. 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
  1. @echo off&SetLocal EnableDelayEdexpansion&cd /d "%~dp0"
  2. Mode Con Cols=130 Lines=30
  3. del /f index.html>nul 2>nul
  4. wget http://www.bathome.net 1>nul 2>nul
  5. for /f "delims=" %%a in (index.html) do (
  6.   set "STR=%%a"
  7.   if defined flag (
  8.     echo 【!cont!】
  9.     call :tiqu "%%a"
  10.     set "flag="
  11.   )
  12.   for %%b in (最新主题 最新回复 热门主题) do (
  13.     if "!STR!" neq "!STR:%%b=!" set "flag=1"&set "cont=%%b"
  14.   )
  15. )
  16. pause&exit
  17. :tiqu
  18. for %%b in ("%~1") do set "str=!str!%%b"
  19. set "str=!str:'= !"
  20. set "str=!str:<= !"
  21. for %%b in (!str!) do (
  22.   set "s=%%b"
  23.   if "%%~xb" == ".html" (
  24.     set "Url=http://www.bathome.net/%%b"
  25.     set "flag1=1"
  26.   )
  27.   if "!s:~0,1!" equ ">" (
  28.     set "t=!s:~1!"
  29.     rem 发现下3句写成 "if not defined flag1 set "Id=!t!" else ("会出错,有时flag1为空时也会显示。
  30.     if not defined flag1 (
  31.       set "Id=!t!"
  32.     ) else (
  33.       set "Title=!t!"
  34.       set "flag1="
  35.       echo 主题:!Title! 发帖ID:!Id! URL:!Url!
  36.     )
  37.   )
  38. )        
  39. goto :eof
复制代码

作者: apang    时间: 2013-1-14 15:38

本帖最后由 apang 于 2013-1-14 21:48 编辑
  1. Set ie = CreateObject("InternetExplorer.Application")
  2. ie.Navigate "http://www.bathome.net"
  3. ie.Visible = False
  4. Do While ie.Busy Or ie.ReadyState <> 4 :Wscript.Sleep 100 :Loop
  5. Text = ie.Document.Body.InnerHtml :ie.Quit
  6. Pattern1 = """>(.*?)</A>.*href=""(thread.*)"">(.*)</A>"
  7. Pattern2 = "id=homegrids_t_[1-3]>(?:(最新主题|最新回复|热门主题))"
  8. Set Re = New RegExp
  9. Re.Pattern =  Pattern1 & "|" & Pattern2
  10. Re.Global = True
  11. Re.IgnoreCase = True
  12. For Each a in Re.Execute(Text)
  13.    Set FSO=CreateObject("Scripting.FilesystemObject")
  14.    Str = "[" & a.SubMatches(3) & "]"
  15.    if Str = "[]" Then
  16.       Str = "主题:" & a.SubMatches(2) & " "
  17.       Str = Str & "发贴ID:" & a.SubMatches(0) & " " & "URL:"
  18.       Str = Str & "http://www.bathome.net/" & a.SubMatches(1)
  19.    End If
  20.    FSO.OpenTextFile("Result.txt",8,True).WriteLine Str
  21.    Set FSO = Nothing
  22. Next
  23. 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

本人的解:
  1. Dim objXML, Url
  2. Url = "http://www.bathome.net"
  3. Set objXML = CreateObject("MSXML2.XmlHttp")
  4. objXML.open "GET", Url, False
  5. objXML.send()
  6. Do Until objXML.readyState = 4 : WScript.Sleep 200 : Loop
  7. Dim objADODB
  8. Set objADODB = CreateObject("Adodb.Stream")
  9. objADODB.Type = 1
  10. objADODB.Mode = 3
  11. objADODB.Open()
  12. objADODB.Write objXML.responseBody
  13. Set objXML = Nothing
  14. Dim objFSO, Temp
  15. Set objFSO = CreateObject("Scripting.FileSystemObject")
  16. Temp = objFSO.GetSpecialFolder(2) & "\"
  17. objADODB.SaveToFile Temp & "bathome.html", 2
  18. Set objADODB = Nothing
  19. Dim objHTML, objIH
  20. Set objHTML = GetObject(Temp & "bathome.html", "HtmlFile")
  21. Do Until objHTML.ReadyState = "complete" : WScript.Sleep 200 : Loop
  22. Dim A, B, objStr
  23. A = Array("最新主题", "最新回复", "热门主题")
  24. B = Array("发帖ID:", "最新回复ID:", "最新回复ID:")
  25. For i = 1 To 3
  26.   objIH = objHTML.GetElementByID("homegrids_c_" & i).InnerHtml
  27.   objStr = objStr & "["& A(i - 1) & "]" & vbCrLf & GetInfo(objIH, B(i - 1)) & vbCrLf
  28. Next
  29. Set objHTML = Nothing
  30. objFSO.DeleteFile Temp & "bathome.html"
  31. objStr = Replace(objStr, "<UL class=textinfolist>" & vbCrLf, "")
  32. objFSO.OpenTextFile("HomePage.txt", 2, True).Write Replace(objStr, vbLf, vbCrLf)
  33. Set objFSO = Nothing
  34. CreateObject("Wscript.Shell").Run "cmd /chomepage.txt", True, False
  35. Function GetInfo(Str1, Str2)
  36.   Dim objRE, Matches, Matche
  37.   Set objRE = New RegExp
  38.   objRE.Global = True
  39.   objRE.IgnoreCase = True
  40.   objRE.Pattern = ".*?"">(.*?)</a.*?(\d{1,}-\d{1,}-\d{1,}).*?"">(.*?)</a.*"
  41.   GetInfo = objRE.Replace(Str1, "主题:$3 " & Str2 & "$1 URL:" & Url & "/thread-$2.html")
  42.   Set objRE = Nothing
  43. 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

额 恶补
  1. set ie = createobject("internetexplorer.application")
  2. ie.visible = false
  3. ie.navigate "http://www.bathome.net"
  4. do until ie.readystate = 4
  5. wscript.sleep 200
  6. loop
  7. Set FSO=CreateObject("Scripting.FilesystemObject")
  8. DIM N,S,var
  9. for i = 0 to 47 step 2
  10.       N = i \ 16
  11.       if i MOD 16 = 0 Then
  12.          var = var & "[" & ie.document.getElementById("homegrids_t_" & N + 1).outerText & "]" & vbcr & vblf
  13.       End If
  14.       if N <> 0 Then
  15.            Str = "主题:" & ie.document.links(i+28).innertext & " " & "最新回复:"
  16.            ELSE Str = "主题:" & ie.document.links(i+28).innertext & " " &"发帖ID:"
  17.       End If
  18.       var= var & str & ie.document.links(i+27).outerText & " " & "URL:" & ie.document.links(i+28).href & vbcr & vblf
  19. Next
  20. FSO.OpenTextFile("Rult.txt",2,True).WriteLine var
  21. ie.quit
  22. Set ie = Nothing
复制代码

作者: terse    时间: 2013-1-19 14:36

搞个三方的 练手 SED 还是有点生疏
  1. @ECHO OFF
  2. set url="http://bbs.bathome.net/"
  3. set s1=最新主题&set "s2=热门主题|最新回复"
  4. set "s=s/<[^\/]*'>([^\/]*)<[^']*'([^']*)'[^<]*'>([^<]*)<\/a><\/li>"
  5. 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
  6. pause
复制代码

作者: tmplinshi    时间: 2013-1-19 15:36

本帖最后由 tmplinshi 于 2013-1-19 16:01 编辑
  1. 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://bathome.net./) Powered by Discuz! 7.2