ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 8252|回复: 22

[分享] 刚学网抓,试着抓了下EH论坛的帖子。

[复制链接]

TA的精华主题

TA的得分主题

发表于 2017-1-20 09:55 | 显示全部楼层 |阅读模式
看了吴姐的网抓教程,试着抓了一下EH论坛VBA版块的帖子,这应该是最简单的网抓实例了,不需要cookie和referer的模拟,更不需要js分析。小白可以参考一下练练手。大神看到了看看能不能指点优化一下,因为速度还是有点慢,一分钟大概才抓70个网页。代码如下
  1. Function strText(ByVal url As String) As String
  2. On Error GoTo UNDEFIND '若异常则返回“访问异常”
  3. DoEvents
  4. With CreateObject("MSXML2.XMLHTTP")
  5.     .Open "GET", url, False
  6.     .Send
  7.     strText = Right(ByteToStr(.responsebody, "gbk"), Len(ByteToStr(.responsebody, "gbk")) - InStr(ByteToStr(.responsebody, "gbk"), "</a>]</em> <a href=""") - Len("</a>]</em> <a href=""") + 1)
  8.     'Debug.Print ByteToStr(.responsebody, "gbk")
  9.     GoTo FUNRETURN '若正正常则返回数据
  10. End With
  11. UNDEFIND: strText = "访问异常"
  12. FUNRETURN:
  13. End Function
  14. Public Sub URL_REPLY()
  15.     t = Timer
  16.     Dim r As Long
  17.     Dim sh As Worksheet
  18.     Set sh = ActiveSheet
  19.     Dim eachurl
  20.     Dim maxrow
  21.     response = strText("http://club.excelhome.net/forum-2-1.html")
  22.     If response = "访问异常" Then
  23.         MsgBox "访问异常"
  24.         Exit Sub
  25.     End If
  26.     On Error Resume Next
  27.     pgcount = Split(Split(response, "class=""last"">... ")(1), "</a>")(0)
  28.     For pg = 1 To Val(pgcount)
  29.     'For pg = 1 To 100
  30.         response = strText("http://club.excelhome.net/forum-2-" & pg & ".html")
  31.         'Debug.Print response
  32.         If response = "访问异常" Then
  33.             MsgBox "访问异常"
  34.             Exit For
  35.         End If
  36.         eachurl = Split(response, "</a>]</em> <a href=""")
  37.         maxrow = sh.UsedRange.Rows.Count
  38.         For i = maxrow + 1 To maxrow + UBound(eachurl) + 1
  39.             sh.Range("A" & i).Value = "http://club.excelhome.net/" & Split(eachurl(i - maxrow - 1), """")(0)
  40.             sh.Range("B" & i).Value = Split(Split(eachurl(i - maxrow - 1), "class=""s xst"">")(1), "</a>")(0)
  41.         Next
  42.         For r = sh.Range("C1048576").End(3).Row + 1 To sh.UsedRange.Rows.Count
  43.             If sh.Range("A" & r).Value <> "" Then
  44.                 result = strText(sh.Range("A" & r).Value)
  45.                 If result = "访问异常" Then
  46.                     sh.Range("C" & r).Value = result
  47.                     sh.Range("D" & r).Value = result
  48.                 Else
  49.                     On Error Resume Next
  50.                     ck = Split(Split(result, "<span class=""xg1"">查看:</span> <span class=""xi1"">")(1), "</span>")(0)
  51.                     hf = Split(Split(result, "<span class=""xg1"">回复:</span> <span class=""xi1"">")(1), "</span>")(0)
  52.                     sh.Range("C" & r).Value = ck
  53.                     sh.Range("D" & r).Value = hf
  54.                 End If
  55.             End If
  56.         Next
  57.     Next
  58.     MsgBox "完成,用时" & Timer - t & "秒"
  59. End Sub
  60. Function ByteToStr(arrByte, strCharset As String) As String
  61.     With CreateObject("Adodb.Stream")
  62.         .Type = 1 'adTypeBinary
  63.         .Open
  64.         .Write arrByte
  65.         .Position = 0
  66.         .Type = 2 'adTypeText
  67.         .Charset = strCharset
  68.         ByteToStr = .Readtext
  69.         .Close
  70.     End With
  71. End Function
复制代码


评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2017-1-20 10:36 | 显示全部楼层
本帖最后由 Kaohsing 于 2017-1-20 10:40 编辑

共有2500页,每页有50条,数据这麽多这还不慢。     strText = ByteToStr(.responsebody, "gbk")
    strText = Right(strText, Len(strText) - InStr(strText, "</a>]</em> <a href=""") - Len("</a>]</em> <a href=""") + 1)

少执行执行ByteToStr()三遍,多少省点时间。

TA的精华主题

TA的得分主题

 楼主| 发表于 2017-1-20 10:41 | 显示全部楼层
Kaohsing 发表于 2017-1-20 10:36
共有2500页,每页有50条,数据这麽多这还不慢。

有什么改进的办法吗?预计爬完这2500*50条需要27小时。。。

TA的精华主题

TA的得分主题

发表于 2017-1-20 11:03 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
kldxlb 发表于 2017-1-20 10:41
有什么改进的办法吗?预计爬完这2500*50条需要27小时。。。

我运行前50页,恢复与查看只有前49条有。网址与表题 以及恢复与查看等项目你是两步走</em> <a href="thread-1325003-1-1.html" class="s xst">刚学网抓,试着抓了下EH论坛的帖子。</a>
<img src="static/image/stamp/011.small.gif" alt="新人帖" align="absmiddle" />
<a href="forum.php?mod=redirect&tid=1325003&goto=lastpost#lastpost" class="xi1">New</a>
</th><td class="by"><cite>
<a href="home.php?mod=space&uid=3631535" c="1">kldxlb</a></cite>
<em><span class="xi1">2017-1-20 09:55</span></em>
</td>
<td class="num"><a href="thread-1325003-1-1.html" class="xi2">1</a><em>41</em></td>
<td class="by">
<cite><a href="home.php?mod=space&username=Kaohsing" c="1">Kaohsing</a></cite>
<em><a href="forum.php?mod=redirect&tid=1325003&goto=lastpost#lastpost">2017-1-20 10:36</a></em>


可以一起split出来,装入数组,最后一次写入单元格,可能还能节省点时间。

TA的精华主题

TA的得分主题

 楼主| 发表于 2017-1-20 12:22 | 显示全部楼层
Kaohsing 发表于 2017-1-20 11:03
我运行前50页,恢复与查看只有前49条有。网址与表题 以及恢复与查看等项目你是两步走 刚学网抓,试着抓了 ...

我想复杂了,原来查看与回复在主页面就可以找到,我还挨个打开查找。。多谢大神指点,下午我改改再发上来

TA的精华主题

TA的得分主题

发表于 2017-1-20 13:12 | 显示全部楼层
kldxlb 发表于 2017-1-20 12:22
我想复杂了,原来查看与回复在主页面就可以找到,我还挨个打开查找。。多谢大神指点,下午我改改再发上来

我说咋反复执行那两个自定义函数,看的眼花缭乱,就没有仔细看下去啦,可能这里浪费了时间。

TA的精华主题

TA的得分主题

 楼主| 发表于 2017-1-20 14:47 | 显示全部楼层
经过kaohsing老师的指点,修改了代码,进度明显加快了。经测试,抓50页2000条仅用77秒
  1. Function strText(ByVal url As String) As String
  2. On Error GoTo UNDEFIND '若异常则返回“访问异常”
  3. DoEvents
  4. With CreateObject("MSXML2.XMLHTTP")
  5.     .Open "GET", url, False
  6.     .Send
  7.     strText = Right(ByteToStr(.responsebody, "gbk"), Len(ByteToStr(.responsebody, "gbk")) - InStr(ByteToStr(.responsebody, "gbk"), "</a>]</em> <a href=""") - Len("</a>]</em> <a href=""") + 1)
  8.     'Debug.Print ByteToStr(.responsebody, "gbk")
  9.     GoTo FUNRETURN '若正正常则返回数据
  10. End With
  11. UNDEFIND: strText = "访问异常"
  12. FUNRETURN:
  13. End Function
  14. Public Sub URL_REPLY()
  15.     t = Timer
  16.     Dim r As Long
  17.     Dim sh As Worksheet
  18.     Set sh = ActiveSheet
  19.     Dim eachurl
  20.     Dim maxrow
  21.     Dim arr
  22.     response = strText("http://club.excelhome.net/forum-2-1.html")
  23.     If response = "访问异常" Then
  24.         MsgBox "访问异常"
  25.         Exit Sub
  26.     End If
  27.     On Error Resume Next
  28.     ReDim arr(1 To 4, 1 To 1)
  29.     For pg = 1 To 50
  30.     'For pg = 1 To 2500
  31.         response = strText("http://club.excelhome.net/forum-2-" & pg & ".html")
  32.         'Debug.Print response
  33.         If response = "访问异常" Then
  34.             MsgBox "访问异常"
  35.             Exit For
  36.         End If
  37.         eachurl = Split(response, "</a>]</em> <a href=""")
  38.         j = 0
  39.         For i = 1 + UBound(arr, 2) To UBound(eachurl) + UBound(arr, 2)
  40.             ReDim Preserve arr(1 To 4, 1 To i)
  41.             arr(1, i) = "http://club.excelhome.net/" & Split(eachurl(j), """")(0)
  42.             arr(2, i) = Split(Split(eachurl(j), "class=""s xst"">")(1), "</a>")(0)
  43.             arr(3, i) = Split(Split(eachurl(j), "</a><em>")(1), "</em>")(0)
  44.             arr(4, i) = Split(Split(eachurl(j), "html"" class=""xi2"">")(1), "</a><em>")(0)
  45.             j = j + 1
  46.         Next
  47.         Application.StatusBar = "正在抓取第" & pg & "页内容"
  48.     Next
  49.     arr(1, 1) = "URL"
  50.     arr(2, 1) = "标题"
  51.     arr(3, 1) = "查看"
  52.     arr(4, 1) = "回复"
  53.     Range("A1").Resize(UBound(arr, 2), 4) = Application.Transpose(arr)
  54.     MsgBox "完成,用时" & Timer - t & "秒"
  55. End Sub
  56. Function ByteToStr(arrByte, strCharset As String) As String
  57.     With CreateObject("Adodb.Stream")
  58.         .Type = 1 'adTypeBinary
  59.         .Open
  60.         .Write arrByte
  61.         .Position = 0
  62.         .Type = 2 'adTypeText
  63.         .Charset = strCharset
  64.         ByteToStr = .Readtext
  65.         .Close
  66.     End With
  67. End Function
复制代码

TA的精华主题

TA的得分主题

发表于 2017-1-20 16:29 | 显示全部楼层
本帖最后由 13907933959 于 2017-1-21 07:54 编辑
kldxlb 发表于 2017-1-20 14:47
经过kaohsing老师的指点,修改了代码,进度明显加快了。经测试,抓50页2000条仅用77秒

前辈好!
我怎么不能运行,提示:编译错误:用户定义类型未定义。

另外、请问一下前辈,有不有办法网抓EH论坛VBA版块指定的帖子,例如:

提取的网址:http://club.excelhome.net/forum. ... digest%26digest%3D1

只提取帖子(包括翻页)每个回复的内容,但不包括回复框内所有的广告、点评、评分…等。

提取代码通过更改网址,也可抓取本论坛上其它帖子的内容。

求前辈赐教!谢谢!

TA的精华主题

TA的得分主题

 楼主| 发表于 2017-1-20 16:35 | 显示全部楼层
13907933959 发表于 2017-1-20 16:29
前辈好!
我怎么不能运行,提示:编译错误:用户类型未定义。

应该是可以的,我写写试试

TA的精华主题

TA的得分主题

发表于 2017-1-20 16:40 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
kldxlb 发表于 2017-1-20 16:35
应该是可以的,我写写试试

感谢前辈帮忙!
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-11-18 14:30 , Processed in 0.036936 second(s), 9 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

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