严格意义来说,采集器和爬虫不是一回事:采集器是对特定结构的数据来源进行解析、结构化,将所需的数据从中提取出来;而爬虫的主要目标更多的是页面里的链接和页面的TITLE。

采集器也写过不少了,随便写一点经验吧,算是给自己的一个备忘。

首先是最简单的:静态页面采集器。即所采集的数据来源页面是静态的,至少采集器所关心的那部分数据是静态的,可以通过直接访问页面URL的方式获取到包含目标数据的全部页面代码。这种采集器是最为常用,也是最为基础的。目前已经有很多成熟的商业化的采集器产品,不过对我来说感觉用着有些过于复杂。一些我自己编写采集器时会注意的问题在这些产品上似乎没有,或者名字不是我拟的那个,找不到。用了几次,干脆不如自己写了,还更省时间效率更高。

准备知识:HTTP协议基础、HTML语言基础、正则表达式和任意支持正则表达式的编程工具(.net、java、php、Python、ruby等等都可以)

首先第一步,是下载目标页面HTML。

这一步并没有什么太难的,.net里有HttpWebRequest和HttpWebResponse等类专门处理,其他语言里也有类似的东西。不过需要注意的是,为采集器编写下载器的时候,参数配置一定要灵活:User-Agent、Refer、Cookie等字段都得做成可配,还得支持使用代理服务器,这是为了突破目标服务器的访问限制策略或机器人识别策略。有关常见的反机器人以及反“反机器人”等相关技术会在后续文章里专门编写。

页面代码下载到本地之后,就得开始对其进行解析。有两种解析方法

1、将其当做HTML解析

熟悉HTML的人可以将下载到的HTML页面直接当做HTML来解析,这样做也是最快和最有效率的。遍历HTML元素和属性之后,直接找到关注部分数据内容,通过访问其元素、元素属性和子元素的方式获取数据。.net里原生没有HTML解析库,可以找第三方库,大多数比较好用,至少当一般拿来解析个页面提个数据之类的够用了。唯一需要注意的是需要考虑页面代码下载不完全或者目标页面结构存在错误的情况。

2、将其当做字符串,用正则表达式解析

正则表达式的好处就是灵活,在方法1失效或者实现麻烦(比如目标数据的HTML元素路径可能不固定)的时候可以考虑。使用正则表达式的思路就是寻找目标数据及其上下文的特征或者特征串,然后编写正则表达式将其匹配提取出来即可。

以下以解析bing的搜索结果页为例,介绍静态采集器工作的基本原理。

首先是页面获取。点击两下就能发现页面参数的规律,举例:

http://cn.bing.com/search?q=MOLLE+II&first=31

这个URL代表以“MOLLE”“II”两个关键词搜索,当前页面是是第四页。FIRST参数指的是本页第一个显示的搜索结果的索引号,第四页显示31-40个搜索结果。

这是用GET方式传递参数,大多数情况下都是这样的。如果目标页面用POST方式传递参数,用浏览器的开发者模式抓个包看看参数是啥就OK了。

然后我们就下载到了目标页面,将其在正则表达式测试器里打开:

恩,这活儿干得多了干脆自己写了一个趁手的工具。

我们的目标是提取到搜索结果里的链接文字和链接URL。对于需要从同一个页面解析得到两项或者多项相互对应的数量一样的数据,也有两种策略:根据这些数据不同的特征直接编写表达式从页面里提取目标数据(比如先用一个正则处理页面,拿到所有的链接标题文字,再用一个正则处理页面,拿到所有的链接URL),或者分析页面结构,找到包含目标数据项的最小页面结构(比如html表格里的表格行<tr>元素),再进行解析。其中后者更靠谱一点,也可以省去很多干扰,但稍微麻烦一些。以下以后一种方式进行介绍。

用浏览器的检查工具(Chrome里以前叫查看元素,新版改叫检查了,刚刚还找了半天)分析页面代码,我们可以发现所有的搜索内容都包含在一个id属性为"b_results"的<ol>标签里。编写表达式对其进行提取:

对于解析HTML用到的正则,零宽断言和逆序环视(查找)是经常用到的,用于提取带有特定前缀和后缀的字符串。有关正则表达式的技术博客园已经有很多相关文章,这里不再赘述。

不过需要注意的是,对于.net的正则表达式库,有一些开关需要注意。对于解析html的时候,经常需要将SingleLine参数选中,这样引擎会把字符串里所有的回车当成普通字符,而不是当成一行数据的结尾。不过这也并非绝对,也需要根据实际情况进行灵活配置。

另外还有一个小技巧。在移动端盛行的今天,一些网站会根据用户浏览器请求里的USER-AGENT提供不同的页面,对手机端发起的请求就会提供手机版的页面,出于节省客户流量的考虑,一般手机版的页面会比PC端的干净一些,页面噪音更少。

继续回到页面解析,刚刚已经找到包含所有目标元素的页面结构,实际上如果发现目标数据的最小结构的特征在页面里也是唯一的,直接提取也无妨:

这样我们就拿到了所有包含目标数据的<li>标签的内容。顺带一提,因为截图里工具使用的NOKIA手机的USER AGENT,所以我拿到的是手机版的页面,和PC版略有不同,更干净一点。

下一步我们对每个元素进行解析。由于所有li标签的格式结构都是一样的,我们可以用同一套正则解析。

我们的目标是链接标题和链接URL,说白了,就是<a>标签的href属性和标签内容。

直接写表达式就好:

然后对于每个li标签的内容使用同样的表达式进行处理就OK了。

好了,采集器的基本原理介绍完毕,我自己写的这个正则工具可以我博客里找到,各位使用愉快,欢迎报BUG和功能建议。

下一篇将会介绍一下动态页面数据获取。

WEB页面采集器编写经验之一:静态页面采集器的更多相关文章

  1. 浅谈php生成静态页面

    一.引 言 在速度上,静态页面要比动态页面的比方php快很多,这是毫无疑问的,但是由于静态页面的灵活性较差,如果不借助数据库或其他的设备保存相关信息的话,整体的管理上比较繁琐,比方修改编辑.比方阅读权 ...

  2. PHP生成静态页面详解

    PHP生成静态页面详解 看到很多朋友在各个地方发帖问PHP生成静态文章系统的方法,以前曾做过这样一个系统,遂谈些看法,以供各位参考.好了,我们先回顾一些基本的概念. 一,PHP脚本与动态页面. PHP ...

  3. ASP.Net MVC如何访问的静态页面

    MVC开发中,因为View文件夹下的web.config文件默认会把任何方法的请求的任何文件,路径都交给 System.Web.HttpNotFoundHandler 去处理.起到Controller ...

  4. SpringMVC与SpringBoot返回静态页面遇到的问题

    1.SpringMVC静态页面响应 package com.sv.controller; import org.springframework.stereotype.Controller; impor ...

  5. 用 Smarty 生成静态页面入门介绍

    why Smarty? 随着公司首页(以下简称首页)流量越来越大,最近开始考虑使用后台语言生成静态页面的技术. 我们知道,一个简单页面一般是一个 .html(或者 .htm ..shtml)后缀的文件 ...

  6. Ruby on Rails Tutorial 第三章 静态页面

    1.生成静态页面 $ rails generate controller StaticPages home help    #生成主页和帮助页面的路由.控制器及静态页面 $ rails destroy ...

  7. Java项目生成静态页面

    第一次做项目需要生成静态页面,网上很多大牛对将网页生成静态页面有很多异议.说一下我的看法. 不外乎有以下因素: 1.从页面加载时间来看:静态页面不需要与数据库建立连接,尤其是访问数据量较大的页面,这种 ...

  8. 使用 gulp-file-include 构建前端静态页面

    前言 虽然现在单页面很流行,但是在 PC 端多页面还是常态,所以构建静态页面的工具还有用武之地.最近也看到了一些询问如何 include HTML 文件的问题. 很多时候我们在写静态页面的时候也希望能 ...

  9. HTML:调用静态页面html 的几种方法

    今天做办公用品管理系统时,发现需要用到在一个静态页面html 中调用多个静态页面html的内容.查找资料总结了以下一些方法: 一.iframe引入的方法 代码如下: <!-- 部门--> ...

随机推荐

  1. 如何关闭emacs开启时自己打开的欢迎界面

    EMACS在开启后,会自动打开一个欢迎界面.如果要去除他,可以在用emacs或其实编辑工具编辑~/.emacs文件. 在最下面一行加上,保存退出即可. (setq inhibit-startup-me ...

  2. LintCode Two Strings Are Anagrams

    1. 把string变为char数组 2. 排序Arrays.sort() public class Solution { /** * @param s: The first string * @pa ...

  3. PL_SQL导入数据库数据

    首先用pl/sql将数据批量导出或者全部导出具体操作如下 点击工具 ----->导出数据---->SQL插入 导出的数据格式如下:   prompt PL/SQL Developer im ...

  4. 解决 502、504 Gateway Time-out(nginx)

    一.504 Gateway Time-out问题常见于使用nginx作为web server的服务器的网站 我遇到这个问题是在升级discuz论坛的时候遇到的 一般看来, 这种情况可能是由于nginx ...

  5. 传统开发模型vs敏捷开发模型——过程模型的变革

    一.概念框架 在了解一个新概念的时候,最好的方法就是把它插入到原有的概念体系中.在不仅有助于对概念的记忆,更利于深刻地认识概念的本质.精髓.下图说明了"敏捷开发"在软件工程理论体系 ...

  6. get_headers()函数

    get_headers() 是PHP系统级函数,他返回一个包含有服务器响应一个 HTTP 请求所发送的标头的数组.如果失败则返回 FALSE 并发出一条 E_WARNING 级别的错误信息(可用来判断 ...

  7. SQL语句小总结

    无论是面试过程中,还是未来工作中,SQL都是一定会考到和用到的.所以,在此对之前看过的一些SQL知识点进行一下总结和记录,算是起到一个笔记本的作用.没有深入学习过SQL的和对SQL印象不太深的朋友可以 ...

  8. 在apache中设置访问目录后进入的默认页面为index.php

    找到apache的配置文件httpd.conf后找到 DirectoryIndex index.html index.php 在其中添加index.php,

  9. html5 EvnetSource 与 JSP页面结合使用

    最近一直在研究前端的技术,特别是html5的技术,本人觉得html5的发展将越来越好,废话少说.看到了EventSource,根据官方的说法是服务器向客户端的推送服务.自己想找一些例子看看,发现都是P ...

  10. VS2010 使用 EntityFramework For SQL Server Compact 4.0

    1.安装 SSCERuntime_x64-ENU.exe 或 SSCERuntime_x86-ENU.exe 2.安装 SSCEVSTools-CHS.msi 3.然后就可以通过 SQL Server ...