网络爬虫的实现原理

何谓网络爬虫

网络爬虫是一种用来抓取网页资源的程序工具。像谷歌,百度等知名搜索引擎就是采用网络爬虫把全网的网页资源收集起来,建立索引,用于搜索。

网络爬虫实现原理

互联网网页可以看成是一张超大图,每个网页是一个节点,网页中指向其他网页的链接是边。那么,可以这样实现全网网页收集:以某一个网页为起点,下载并处理该网页,解析里面的链接,所得的URL加入下载队列。这个过程其实就是图的遍历过程,可以是深度优先或者广度优先遍历,取决于下载队列如何维护。简单地,网络爬虫可以由以下部分组成:

下载模块

对于一个给定的URL,下载该网页。如果从零开始实现,工作量还是挺大的:①解析URL里面的域名并通过DNS查询域名对应的IP;②建立一个到该IP的TCP连接;③发送一个HTTP请求;④接收并解析HTTP响应;⑤保存该网页资源。说白了,就是给定一个URL,用HTTP协议请求一个网页资源的过程。

下载队列

下载队列保存从网页中解析出来将用于获取网页资源的URL:每次从下载队列里面取出一个URL,通过下载模块下载该网页,解析该网页里面的URL并加入下载队列,这样就可以源源不断地进行网页抓取。如果用FIFO实现下载队列,那么对网页资源的遍历就是广度优先的;如果用LIFO实现下载队列,那么对网页资源的遍历就是深度优先的。

重复检查

如果某个网页里面包含了已经下载的网页的URL怎么办呢?肯定不能再重复下载一次。如何避免就是重复检查模块要做的事。可以用一个set把所有遇到的URL记录下来,每次下载模块获取一个网页,将其URL放到该set;解析网页所获得的URL,如果在该set中已经存在了,就不要加入下载队列了。当然了,这只是最直白的实现方式,工程上为了应对大量的URL,一般采用布隆过滤器。

Python实现举例

 
  1. #!/usr/bin/env python

  2. # -*- encoding=utf8 -*-

  3.  
  4. import re, urllib2, md5, urlparse

  5.  
  6. class Crawler(object):

  7. def __init__(self, *starts):

  8. self.seen = set() # 已获取网页的URL集合

  9. self.queue = [] # 待下载队列

  10. self.URLMOD = re.compile('href="(http://[^"]*)"') # 用于匹配URL的正则

  11.  
  12. # 将起点URL加入下载队列

  13. for start in starts:

  14. self.queue.append(start)

  15.  
  16. def process(self, url, res):

  17. # 正则解析网页里面的URL

  18. for new_url in self.URLMOD.findall(res):

  19. if new_url.find('\n') == -1 and new_url not in self.seen:

  20. # 如果URL不在已获取集合,则加入下载队列

  21. self.queue.append(new_url)

  22.  
  23. # 在这里写个性化的网页处理逻辑:保存到文件?写到数据库?

  24.  
  25. def run(self):

  26. while self.queue:

  27. # 从下载队列取出一个URL

  28. url = self.queue.pop()

  29.  
  30. try:

  31. # 下载该网页:用Python的urllib2

  32. res = urllib2.urlopen(url, timeout=10).read()

  33. print 'Get %s %s' % (url, '')

  34. except:

  35. # 下载出错

  36. print 'Err %s %s' % (url, '')

  37. continue

  38.  
  39. # 将URL加入已获取集合

  40. self.seen.add(url)

  41.  
  42. # 处理该网页

  43. self.process(url, res)

  44.  
  45. if __name__ == '__main__':

  46. Crawler('http://www.baidu.com').run()

猜你喜欢

转载自blog.csdn.net/qq_42809504/article/details/83049564