爬虫的工作流程大致如下,
下载html --> 提取内容与url --> 调度 --> 继续下载...
今日打算谈谈我对于提取内容与url的看法。
传统方案
xpath,××soup,××query之类的库,实现简单,而且可以直接从浏览器中拷贝路径。其实就是默认html中的元素都有严格规范的标签。(不过很多html都写得很随意,拷贝的xpath是经过浏览器容错修改后的,到手后常常需要继续调试)
这种做法和浏览器解析网页十分类似,称之为“精准定位”。浏览器对于元素的呈现规则十分严格,并不会在意href是内链还是外链,也不会遗漏html中的次要元素,甚至并不会区分元素的“重要性”。显然严格遵循这套规则去解析网页,对转移信息到数据库中并没有啥帮助,例如数据源来自1000个站点,或许就需要写1000套提取方案,并作出后期维护。
提取url
可以总结站点对于信息呈现的规律,以常见的类似书籍的“目录-内容”结构为例。
- 目录下,一定包含内容的链接,以及指向下一页或者前一页的链接
- 目录的url与其他目录url相似,内容页url与其他内容u页url相似。
相信这两点对于大部分网站都适用,难点在于大型网站url的深度更深,结构可能更加复杂。但是,以此为立足点去看待原有的问题,就会非常简单--仅仅需要计算url的相似度。我希望的方案是尽量符合人的判断标准,将url进行拆分。python3中urllib.parse.urlparse 将url解析成好几个片段,基于这些片段可以做出统计,然后给定一个阈值就可以做一个简单的分类。
提取正文
为了更好的表达,我对于常见文本类html内容作出一下划分
- 定义: 主体,背景,分支,噪音
- 主体,html主要信息呈现
- 背景,区分不同站点,网站基本介绍-内链-js脚本,和主体在一个量级
- 分支,主体的不同段落,呈现主体的结构
- 噪音,夹在在分支之间的无关信息,比如会员登录提示,和分支一个量级
以百度搜索的结果页为例,顶部的搜索栏与右边的推荐我认为是背景,整个搜索结果我认为是主体,各个相关搜索结果是分支,其中的“商业推广”我认为是噪音。
同一站点内
- 假设
- 背景与主体的位置一致
- 背景相似,甚至相同
- 相似主题的html噪音相似
对于相同的背景可以对比两个html的将其去除,甚至js脚本可以根据在dom树里的tag直接去除。通常到这一步已经可以获取比较干净的内容,比如想离线浏览小说的宅友们。后面难点在于对于噪音的清洗,如果噪音与背景一样都是完全相同或者说是js脚本,或者有类似“推广”的标签,那就很容易。目前还在探索中。
总结
基于html标签的做法,“假设每个元素都有唯一的标签”,足够通用(本来就是标记语言)但不细致。那么想作出通用爬虫,就必须作出通用并且细致的假设。