首页 | Linux 基础 | 资讯动态 | Linux 应用 | Linux 服务器 | Linux 开发 | Linux 安全 | 专题 | 联盟论坛
  当前位置:主页>Linux 服务器>linux服务器应用>文章内容
在 Linux 上构建 Web spider
来源:www.unix5.com 作者:riechelr_hl 发布时间:2007-06-05  


图 1. 清单 5 中的 Ruby 脚本发送的 E-mail 警告
 

至此对 scraper 的介绍就告一段落,接下来将深入地了解一下 Web spider 的构建。

例子 4: Web 站点爬虫

在最后这个例子中,将探索一下在 Web 站点上爬行的 Web spider。为了安全起见,我将避免在该站点之外浪费时间,而只会深入研究一个 Web 页面。

要在 Web 站点上爬行并访问这个站点上所提供的链接,必须要对 HTML 页面进行解析。如果可以成功解析 Web 页面,就可以确定到其他资源的链接,这些链接有些指定的是本地资源(文件),而有些则会代表非本地的资源(例如到其他 Web 页面的链接)。

要在 Web 上爬行,需要从一个给定的 Web 页面开始,确定这个页面中的所有链接,将它们放入一个等待访问的队列中进行排序,然后使用等待访问队列中的第一项来重复这个处理过程。这会产生广度优先遍历(与优先处理首先找到的第一个链接不同,后者是一种深度优先遍历)。

如果能够避免非本地的链接而只访问本地 Web 页面,就可以为这个单一 Web 站点提供 Web 爬虫了,如清单 7 所示。在本例中,使用 Python 语言来代替 Ruby 语言,这样做是为了利用 Python 非常有用的 HTMLParser 类。


清单 7. 简单的 Python Web 站点爬虫(minispider.py)
#!/usr/local/bin/python

import httplib
import sys
import re
from HTMLParser import HTMLParser


class miniHTMLParser( HTMLParser ):

  viewedQueue = []
  instQueue = []

  def get_next_link( self ):
    if self.instQueue == []:
      return ''
    else:
      return self.instQueue.pop(0)


  def gethtmlfile( self, site, page ):
    try:
      httpconn = httplib.HTTPConnection(site)
      httpconn.request("GET", page)
      resp = httpconn.getresponse()
      resppage = resp.read()
    except:
      resppage = ""

    return resppage


  def handle_starttag( self, tag, attrs ):
    if tag == 'a':
      newstr = str(attrs[0][1])
      if re.search('http', newstr) == None:
        if re.search('mailto', newstr) == None:
          if re.search('htm', newstr) != None:
            if (newstr in self.viewedQueue) == False:
              print "  adding", newstr
              self.instQueue.append( newstr )
              self.viewedQueue.append( newstr )
          else:
            print "  ignoring", newstr
        else:
          print "  ignoring", newstr
      else:
        print "  ignoring", newstr


def main():

  if sys.argv[1] == '':
    print "usage is ./minispider.py site link"
    sys.exit(2)

  mySpider = miniHTMLParser()

  link = sys.argv[2]

  while link != '':

    print "\nChecking link ", link

    # Get the file from the site and link
    retfile = mySpider.gethtmlfile( sys.argv[1], link )

    # Feed the file into the HTML parser
    mySpider.feed(retfile)

    # Search the retfile here

    # Get the next link in level traversal order
    link = mySpider.get_next_link()

  mySpider.close()

  print "\ndone\n"

if __name__ == "__main__":
  main()

这个爬虫的基本设计是加载第一个链接并将其放入一个队列。此队列就是下一个要询问 (next-to-interrogate) 队列。当一个链接被选中时,所发现的任何新链接都被加入相同的队列中。这提供了一种广度优先的搜索。另外还维护了一个已查看过的队列以防止再次访问过去已经查看过的链接。基本上就这些,很多实际工作都可以由 HTML 解析器来完成。

先是从 Python 的 HTMLParser 类获取一个新类 miniHTMLParser。这个类可以实现几个功能。首先,它可以用作 HTML 解析器,只要碰到开始的 HTML 标记都会提供一个回调方法 (handle_starttag)。其次,这个类还可以用来访问在爬行中所碰到的链接 (get_next_link) 并检索这个链接所代表的文件(在本例中是一个 HTML 文件)。

这个类中还包含了两个实例变量:viewedQueue,其中包含了到目前为止已经检查过的链接;instQueue,表示将要被审查的链接。

正如您所见,类方法非常简单。get_next_link 方法检查 instQueue 是否为空,并返回 ''。否则,就通过 pop 方法返回下一项。gethtmlfile 方法使用 HTTPConnectionK 连接到站点上并返回指定页面的内容。最后,对 Web 页面中的每个开始标记都调用 handle_starttag(它是通过 feed 方法传递给 HTML 解析器的)。在这个函数中,检查该链接是否是非本地链接(如果链接中包含 http),是否是 e-mail 地址(如果包含 mailto),以及链接中是否包含 'htm',如果包含则说明它(有很大的可能)是一个 Web 页面。另外还会检查以确保之前没有访问过这个链接;否则,就将这个链接加载到已经审查过的队列中。

共6页: 上一页 [1] [2] [3] 4 [5] [6] 下一页
 
如果您对本文有任何疑问或者建议,请到论坛讨论区发表您的意见: >> 论坛入口
[收藏] [推荐] [评论(0条)] [返回顶部] [打印本页] [关闭窗口]  
  热点文章
·用Samba实现文件服务器功能
·在Linux上建立DNS服务器
·在linux下设置WWW Server
·用Linux建立局域网服务器
·如何设定管理SAMBA网络邻居服务
·如何建造Open WebMail伺服器(图
·如何建造Open WebMail伺服器二(
·DNS 基本观念与实际运用(图文讲
·Linuxconf DHCP伺服器架設与管理
·Linux系统下基于NUMA构建的服务
  相关文章
·在Linux上建立DNS服务器
·在linux下设置WWW Server
·用Samba实现文件服务器功能
·用Linux建立局域网服务器
·如何设定管理SAMBA网络邻居服务
·如何建造Open WebMail伺服器(图
·如何建造Open WebMail伺服器二(
·DNS 基本观念与实际运用(图文讲
·Linuxconf DHCP伺服器架設与管理
·Linux系统下基于NUMA构建的服务

本站信息源至:互联网络,均为学习,交流所用,如有版权问题,请联系我们.
站长QQ:397422079 E_mail:riechelr_hl@unix5.com
转载本站内容请注明原作者名.谢谢!