爬虫初探系列一共 4 篇, 耐心看完, 我相信你就能基本了解爬虫是怎样工作的了, 目录如下:
python 爬虫初探(一): 爬虫的基本结构
python 爬虫初探(二):URL 管理器和下载器
python 爬虫初探(三):html 解析器
折腾君: python 爬虫初探(四): 数据存储器
代码已上传至 github, 在 python2.7 下测试成功(请原谅我浓浓的乡村非主流代码风格)summerliehu/SimpleSpiderFramework
爬虫是个很奇妙的东西, 这也是 python 的魅力所在用非常简单的代码就能打造出一个功能强大的爬虫, 去爬取你想收集的信息, 将人类的双手从重复的工作中解放出来但是, 很多初学者往往在搞懂爬虫的基本原理上就下了很大的功夫, 一段时间以来, 我在学习 python 爬虫的过程中颇有心得体会, 在这里稍加总结, 希望能够给各位初学者一点启发
爬虫, 顾名思义, 就是能够自主的对目标网页上的信息进行采集, 并将采集到的数据进行存储的程序对于爬虫的基本流程, 已经有很多人对此进行了总结然而, 目前网上大部分对爬虫原理的讲解都过于复杂且晦涩难懂, 难以为初学者所理解所以我在这里根据自己的理解将爬虫爬取网络的过程画了下来, 其基本的运行过程可以总结为下图(突然发现这个过程和生物学中的 TCA cycle 非常类似, 事实上分子生物学正是我的专业!)
爬虫对目标网页爬取的过程可以参考下面黑色文字部分:
首先访问初始 url, 获取其相应内容
对相应内容进行解析, 提取感兴趣的信息和新的链接
将上一步提取到的数据存储, 将获取到的链接去重并存储至仓库
从 url 仓库获得一条未爬取过的 url, 开始新的循环
图片中由黑色文字组成的循环应该很好理解, 那么具体到编程上来说, 则必须将上面的流程进行抽象, 我们可以编写几个元件, 每个元件完成一项功能, 上图中的蓝底白字就是对这一流程的抽象:
UrlManager: 将存储和获取 url 以及 url 去重的几个步骤在 url 管理器中完成(当然也可以针对每一步分别编写相应的函数, 但是这样更直观)url 管理器要有两个 url 仓库, 一个存储未爬取的 url, 一个存储已爬取的 url, 除了仓库之外, 还应该具有一些完成特定功能的函数, 如存储 urlurl 去重从仓库中挑选并返回一个 url 等
HtmlDownloader: 将下载网页内容的功能在 HTML 下载器中完成, 下载器的功能较为单一, 不多解释但从整个爬虫的角度上来说, 下载器是爬虫的核心, 在实际操作的过程中, 下载器要和目标网站的各种反爬虫手段斗智斗勇(各种表单隐藏字段和假链接验证码 IP 限制等等), 这也是最耗费大脑的步骤
HtmlParser: 解析提取数据的功能在 HTML 解析器中完成, 解析器内的函数应该分别具有返回数据和新 url 的功能
DAtaOutput: 存储数据的功能由数据存储器完成
SpiderMan: 主循环由爬虫调度器来完成, 调度器为整个程序的入口, 将其余四个元件有序执行
OK, 具体流程就是这样了, 下面的图可能更加清楚一些:
爬虫调度器将要完成整个循环, 下面写出 python 下爬虫调度器的程序:
# coding: utf-8new_urls = set()data = {}class SpiderMan(object): def __init__(self): #调度器内包含其它四个元件, 在初始化调度器的时候也要建立四个元件对象的实例 self.manager = UrlManager() self.downloader = HtmlDownloader() self.parser = HtmlParser() self.output = DataOutput() def spider(self, origin_url): #添加初始 url self.manager.add_new_url(origin_url) #下面进入主循环, 暂定爬取页面总数小于 100 num = 0 while(self.manager.has_new_url() and self.manager.old_url_size()<100): try: num = num + 1 print '正在处理第 {} 个链接'.format(num) #从新 url 仓库中获取 url new_url = self.manager.get_new_url() #调用 html 下载器下载页面 html = self.downloader.download(new_url) #调用解析器解析页面, 返回新的 url 和 data try: new_urls, data = self.parser.parser(new_url, html) except Exception, e: print e for url in new_urls: self.manager.add_new_url(url) #将已经爬取过的这个 url 添加至老 url 仓库中 self.manager.add_old_url(new_url) #将返回的数据存储至文件 try: self.output.store_data(data) print 'store data succefully' except Exception, e: print e print '第 {} 个链接已经抓取完成'.format(self.manager.old_url_size()) except Exception, e: print e #爬取循环结束的时候将存储的数据输出至文件 self.output.output_html()
存储器下载器解析器和 url 管理器将在随后的文章中给出分析
本文的写作过程中参考了以下资料:
Python 爬虫开发与项目实战, 范传辉 编著
Python 网络数据采集[美] 米切尔(Ryan Mitchell) 著
Python 爬虫学习系列教程(来自崔庆才的博客)
来源: http://www.92to.com/bangong/2018/02-03/33263582.html