WEB页面采集器编写经验之一:静态页面采集器

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

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

时间: 2024-11-04 12:10:14

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

浅谈php生成静态页面

一.引 言 在速度上,静态页面要比动态页面的比方php快很多,这是毫无疑问的,但是由于静态页面的灵活性较差,如果不借助数据库或其他的设备保存相关信息的话,整体的管理上比较繁琐,比方修改编辑.比方阅读权限限制等,但是,对应一些我们经常频频使用的文件,比方说,开发的新闻发布系统,我们不希望很多用户都读取数据库才显示结果,这样一方面消耗了服务器的资源,另一方面占去了浏览者大量可贵的响应时间,所有,有了"静态页面话"的做法,当前很多网站都采用这种技术,一般都是由管理后台控制,或者生成html直

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

MVC开发中,因为View文件夹下的web.config文件默认会把任何方法的请求的任何文件,路径都交给 System.Web.HttpNotFoundHandler 去处理.起到Controller统一控制的效果. <httpHandlers> <add path="*" verb="*" type="System.Web.HttpNotFoundHandler"/></httpHandlers> 现在项目需

Java项目生成静态页面

第一次做项目需要生成静态页面,网上很多大牛对将网页生成静态页面有很多异议.说一下我的看法. 不外乎有以下因素: 1.从页面加载时间来看:静态页面不需要与数据库建立连接,尤其是访问数据量较大的页面,这种页面大多要查很多结果集,因此建立连接次数就增多了,时间不可观,而静态页面则省去了这些时间. 2.从便于搜索引擎抓取的角度来讲:搜索引擎更喜欢静态的网页,静态网页与动态网页相比,搜索引擎更喜欢静的,更便于抓取,搜索引擎SEO排名更容易提高,一些大门户站页面大多都采用静态或伪静态网页来显示,更便于搜索引

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

前言 虽然现在单页面很流行,但是在 PC 端多页面还是常态,所以构建静态页面的工具还有用武之地.最近也看到了一些询问如何 include HTML 文件的问题. 很多时候我们在写静态页面的时候也希望能和后台模板一样,将导航.页头.页脚等公用的部分分离出去,然后引入页面中.单纯的静态页面不具备这种功能,而使用 gulp 插件可以很容易的完成,比如 gulp-file-include 插件. 官网对于插件的基本使用已经说得很详细,但是对于一些具体的场景并没有举例,所以初次接触还是还是会有疑惑,比如具

熟悉基于JSP和Servlet的Java Web开发,对Servlet和JSP的工作原理和生命周期有深入了解,熟练的使用JSTL和EL编写无脚本动态页面,有使用监听器、过滤器等Web组件以及MVC架构模式进行Java Web项目开发的经验。

熟悉基于JSP和Servlet的Java Web开发,对Servlet和JSP的工作原理和生命周期有深入了解,熟练的使用JSTL和EL编写无脚本动态页面,有使用监听器.过滤器等Web组件以及MVC架构模式进行Java Web项目开发的经验. 1.说一说Servlet生命周期(非常重要) Servlet生命周期包括三部分: 初始化:Web容器加载servlet,调用init()方法 只执行一次 处理请求:当请求到达时,运行其service()方法.service()自动调用与请求相对应的doXXX

mac os x 之通过远程主机在nginx上部署web静态页面

1.mac使用ssh命令登陆远程主机 因为苹果mac os x自带ssh命令,所以我们只需打开终端输入 $ ssh [email protected] 在这之前最好在服务器上上传自己的ssh key,避免每次登陆输入密码 稍作等待就连接上服务器了   2.mac使用scp命令向远处主机上传文件 在终端窗口,按下command+n,打开另一个终端窗口,并输入 $ scp ~/local/file [email protected]:~/file  当然一般我们上传的是文件夹,所以加上-r $ sc

处女作——静态页面的编写

商城商品管理页面(静态页面) 1. 头部导航条 2. 菜单列表 3. 搜索选项 4. 热门搜索 5. 商品列表(图片,价格,购买按钮) <!DOCTYPE html> <html> <head lang="en"> <meta http-equiv="content-type" content="text/css" charset="UTF-8"> <title>乐美

在 app 界面布局和静态页面编写之前需要了解的事

相信大家已经对 APICloud 平台及其开发流程有了基本的了解.本篇文章要和大家讨论怎样从零起步开发一款 app,首先明确的是要开发一款什么样的app. 以开发一款 O2O 类型的电商 app为例,大家可以在<30天,App开发从0到1>这本书的开源仓库 a 中下载这个 app 的 Android 和 iOS 安装包.安装完毕后,运行这个 app 体验并查看功能. 在开发这款 app 之前需要先做一系列的准备工作,内容包括: 需求梳理,输出需求说明文档; UE 设计,输出产品原型; ? UI

关于线上静态页面资源更新的一些经验分享

目录 关于线上静态页面资源更新的一些经验分享 关于Linux的Patch 关于git 关于Idea 关于线上静态页面资源更新的一些经验分享 最近在负责公司的后台项目,包括了后端和前端.后端直接编译完打成jar包直接上线运行没什么问题.但是前端的页面文件更新每次都要把页面给运维,然后告诉运维路径让运维挨个替换,当然也可以整包替换, 但是如果文件比较多的情况下,整包替换就不合适了.因为现在开发的项目版本控制基本必不可少了,这时候可以利用版本控制软件来生成Patch文件,然后直接交给运维,让运维在项目