SuperSpider——打造功能强大的爬虫利器

SuperSpider——打造功能强大的爬虫利器

 

博文作者:加菲

发布日期:2013-12-11

阅读次数:4506

博文内容:

 

1.爬虫的介绍

图1-1  爬虫(spider)

      
      网络爬虫(web spider)是一个自动的通过网络抓取互联网上的网页的程序,在当今互联网中得到越来越广泛的使用。这种技术一般用来爬取网页中链接,资源等,当然,更为高级的技术是把网页中的相关数据保存下来,成为搜索引擎,例如著名的google和百度。常见的爬虫应用还有像一淘这样的比价网站,电影推荐网站等。

      为了让大家进一步感受到爬虫的魅力,笔者编写了一个爬取淘宝和京东数据的比价网站(http://jiafei.org:8888/),如图1-2所示。由于淘宝和京东的搜索结果页面中有部分内容引(如价格)是通过ajax动态获得的,再用javascript把内容写入到相应的标签中的,当搜索Iphone 5s时,后台爬虫利用webkit生成去最终的dom树,爬取有用的数据,经过简单的处理后返回相应的结果。

 

图1-2  一个简单的比较网站

 

2.为何需要爬虫

      爬虫对于扫描器来说至关重要,站在整个扫描器的最前线(如图2-1所示)。在一个专业扫描器中,一般首先会由爬虫爬取指定的页面,接着把爬到的url传递给调度server,最后由调度server分发需要扫描的url给扫描agent来完成整个扫描过程。

 

图2-1  扫描器的组成

 

2.爬虫的架构与分析

 
      Web安全对于互联网公司来说至关重要,为了让公司的扫描器与业界的扫描器看齐,server安全组自研了一款功能强大的爬虫——SuperSpider,主要用来为漏洞扫描提供丰富的urls。SuperSpider的架构如图3-1所示,首先由下载器模块下载指定的页面,分析页面模块分析完成后一方面把需要的数据传递给存储模块,另一方面将爬取的urls传递给去重模块,去重后放到url队列中,最后由调度器安排次序传递url给下载器下载新的页面。接下来详细讲讲分析页面,调度器和去重这3个模块。

 

图3-1  爬虫的架构

 

3.1分析页面


简单的来说, 爬虫主要作用就是用来分析页面。

难点:因为现在是web2.0时代,绝大部分网页都会使用javascript处理页面,而且很多网页内容都是通过Ajax技术加载的。因此,只是简单地解析HTML文件会远远不够。

解决:如何做到这点?编写一个基于webkit的爬虫SuperSpider。下面将详细说明SuperSpider所具有的5个功能强大的爬取能力。

a.  静态页面链接分析


      简单点来说,就是分析html文档,例如下图的一个<a>标签的超链接,SuperSpider会识别出href中的值为一个超链接,提取其值html_link.php?id=1。

b.  javascript动态解析


      下图为一段javascript代码,该代码的目的是在id为hi的a标签中提交属性href。



      
      SuperSpider利用webkit内核执行以上javascript代码生成出以下html代码,再通过静态页面链接分析获取js_link.php?id=1&msg=abc这个url。


c.  自动分析表单


      SuperSpider会自动识别出action中的值为所提交的地址,提取input标签中的name和value作为参数,最终生成出 post_link.php?id=1&msg=abc 这个url。

 


d.  自动交互

      自动交换就是说要模仿出人的行为,例如点击鼠标,按下回车键等,下图就是一个需要点击鼠标的例子。


      SuperSpider会自动识别出onclick是一个交换行为,从而执行里面的js代码生成出以下html,从而爬到了 click_link.php?id=1 这个url。

 

e.  hook所有的网络请求

      这是一个ajax请求,有别于以上4种基于dom树解析的分析技术,要捉到其请求的url只能通过hook请求,而webkit文档中并没有提到hook 网络请求的方法。于是通过修改webkit代码hook住每一个由webkit发送出去的请求,从而拿到了 ajax_link.php?id=1&t=1这个url。

 


3.2调度器


      SuperSpider的调度器使用广度优先搜索策略,具体的逻辑如下图所示。首先,从入口页面1.html中爬到了2.html, 3.html和4.html,依次把它们放到url队列中。接着取出2.html,把爬到的5.html和6.html放到url队列中,随后便开始爬取3.html,依广度次序进行。

图3-2-1  爬虫调度的广度优先搜索策略


3.3去重

      为了扫描的质量和效率,需要进行去重。例如大部分网站中日期作为其url的组成部分,尤其是门户网站。SuperSpider使用将数字替换成d+的算法对url进行去重。例如,

1.http://video.sina.com.cn/ent/s/h/2010-01-10/163961994.shtml?a=1&b=10

2.http://video.sina.com.cn/ent/s/h/2009-12-10/16334456.shtml?a=12&b=67

对数字进行模式处理为:

http://video.sina.com.cn/ent/s/h/d+-d+-d+/d+.shtml?a=d+&b=d+

如果链接1已经爬取过,链接2与链接1类似, 不重复爬取。

试验证明这种方法简捷高效,漏爬率极低,大大提升扫描器的效率。

 

4.爬虫的具体实现


a.webkit的易用性


      常用的chrome, safari等浏览器都是基于webkit内核,不过提起这个内核,大家可能会觉得有点庞大艰深。但如果只是对于应用层面来说,webkit使用起来还是挺简易的。如图4-1所示,只需14行便可以写出一个浏览器。

图4-1  使用webkit编写的浏览器

b.难点解决


问题:Webkit需要视窗系统才能正常启动,而服务器一般都没有视窗系统的,那么如何在后台稳定地运行webkit?之前是去掉webkit中的图形渲染,css等与gui有关的代码,太麻烦,易出众多bug。


解决:使用xvfb虚拟出一个视窗系统,只需把alert, confirm, prompt的代码注释掉(因为会让浏览器卡住),简单快捷稳定。


c.爬虫的逻辑代码


图4-2为爬虫的逻辑代码,在parse函数里利用webkit生成出来的dom树来做具体的第三部分所提到的分析逻辑。

图4-2  爬虫的逻辑代码



5.效果

      SuperSpider与wvs的爬虫对比,在著名的爬虫测试平台http://demo.aisec.cn/demo/进行测试,该平台要求爬虫要完全具备3.1所提到的5个功能才能爬取到所有的url,上图为扫描器的爬虫,下图为wvs的爬虫, 其中click_link.php (在3.1.d提到)是需要爬虫具有自动交换能力才能爬取到的。

结论:SuperSpider全部都能爬到, 在自动交互方面比wvs表现更好

图4-1  SuperSpider与wvs的结果对比

 

6.结尾


以上笔者的一些思考与总结,欢迎大牛们的意见和建议!

转载于:https://www.cnblogs.com/mfryf/p/3660640.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/377141.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《MySQL——关于grant赋权以及flush privileges》

先上总结图&#xff1a; 对于赋予权限或者收回权限还是创建用户&#xff0c;都会涉及两个操作&#xff1a; 1、磁盘&#xff0c;mysql.user表&#xff0c;用户行所有表示权限的字段的值的修改 2、内存&#xff0c;acl_users找到用户对应的对象&#xff0c;将access值修改 g…

《MySQL 8.0.22执行器源码分析(1)——execute iterator一些记录》

目录一条语句的函数调用栈顺序8.0使用迭代器模式改进executorint *handler*::ha_rnd_next(*uchar* **buf*)int *TableScanIterator*::Read()int FilterIterator :: Read&#xff08;&#xff09;int HashJoinIterator::Read()int NestedLoopIterator :: Read&#xff08;&#…

strcspn函数

函数原型&#xff1a;extern int strcspn(char *str1,char *str2) 参数说明&#xff1a;str1为参照字符串&#xff0c;即str2中每个字符分别与str1中的每个字符比较。 所在库名&#xff1a;#include <string.h> 函数功能&#xff1a;以str1为参照&#xff0c…

MongoDB源码概述——内存管理和存储引擎

数据存储&#xff1a; 之前在介绍Journal的时候有说到为什么MongoDB会先把数据放入内存&#xff0c;而不是直接持久化到数据库存储文件&#xff0c;这与MongoDB对数据库记录文件的存储管理操作有关。MongoDB采用操作系统底层提供的内存文件映射&#xff08;MMap&#xff09;的方…

SharePoint 2010 Form Authentication (SQL) based on existing database

博客地址 http://blog.csdn.net/foxdaveSharePoint 2010 表单认证&#xff0c;基于现有数据库的用户信息表本文主要描述本人配置过程中涉及到的步骤&#xff0c;仅作为参考&#xff0c;不要仅限于此步骤。另外本文通俗易懂&#xff0c;适合大众口味儿。I. 开启并配置基于声明的…

小狐狸ChatGPT系统 不同老版本升级至新版数据库结构同步教程

最新版2.6.7下载&#xff1a;https://download.csdn.net/download/mo3408/88656497 小狐狸GPT付费体验系统如何升级&#xff0c;该系统更新比较频繁&#xff0c;也造成了特别有用户数据情况下升级时麻烦&#xff0c;特别针对会员关心的问题出一篇操作教程&#xff0c;本次教程…

HDUOJ---1754 I Hate It (线段树之单点更新查区间最大值)

I Hate It Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 33469 Accepted Submission(s): 13168 Problem Description很多学校流行一种比较的习惯。老师们很喜欢询问&#xff0c;从某某到某某当中&#xff0c;…

C# 把数字转换成链表

例如&#xff1a;123456转换成 1 -> 2 -> 3-> 4-> 5-> 6 View Code static LinkedList<int> CovertIntToLinkedList(int num){Stack<int> stack new Stack<int>();LinkedList<int> result new LinkedList<int>();while (num!0…

《MySQL 8.0.22执行器源码分析(4.1)Item_sum类以及聚合》

Item_sum类用于SQL聚合函数的特殊表达式基类。 这些表达式是在聚合函数&#xff08;sum、max&#xff09;等帮助下形成的。item_sum类也是window函数的基类。 聚合函数&#xff08;Aggregate Function&#xff09;实现的大部分代码在item_sum.h和item_sum.cc 聚合函数限制 不…

Java 性能优化实战记录(2)---句柄泄漏和监控

前言: Java不存在内存泄漏, 但存在过期引用以及资源泄漏. (个人看法, 请大牛指正) 这边对文件句柄泄漏的场景进行下模拟, 并对此做下简单的分析.如下代码为模拟一个服务进程, 忽略了句柄关闭, 造成不能继续正常服务的小场景. 1 public class FileHandleLeakExample {2 3 p…

骑士游历问题问题_骑士步行问题

骑士游历问题问题Problem Statement: 问题陈述&#xff1a; There is a chessboard of size NM and starting position (sx, sy) and destination position (dx,dy). You have to find out how many minimum numbers of moves a knight goes to that destination position? 有…

Android基础之用Eclipse搭建Android开发环境和创建第一个Android项目(Windows平台)...

一、搭建Android开发环境 准备工作&#xff1a;下载Eclipse、JDK、Android SDK、ADT插件 下载地址&#xff1a;Eclipse:http://www.eclipse.org/downloads/ JDK&#xff1a;http://www.oracle.com/technetwork/java/javase/downloads/jdk7u9-downloads-1859576.html Android SD…

《dp补卡——01背包问题》

目录01背包[416. 分割等和子集](https://leetcode-cn.com/problems/partition-equal-subset-sum/)[1049. 最后一块石头的重量 II](https://leetcode-cn.com/problems/last-stone-weight-ii/)[494. 目标和](https://leetcode-cn.com/problems/target-sum/)01背包 1、dp数组以及…

用JavaScript往DIV动态添加内容

参考&#xff1a;http://zhidao.baidu.com/link?url6jSchyqPiEYCBoKdOmv52YHz9r7MTBms2pK1N6ptOX1kaR2eg320mlW1Sr6n36hpOeOadBxC2rWWGuhZPbms-K <div id"show"></div>要填充的数据为: 这是一个测试例子.jquery&#xff1a;$(function(){ var data …

《dp补卡——完全背包问题》

N件物品和一个最多能背重量为W的背包。第i件物品的重量为weight[i]&#xff0c;得到的价值是value[i]。每件物品都有无限个(可以放入背包多次)&#xff0c;求解将哪些物品装入背包里物品价值总和最大。 01背包和完全背包唯一不同在于遍历顺序上。 01背包的核心代码&#xff1a…

《dp补卡——多重背包》

多重背包简介&#xff1a; 有N种物品和一个容量为V的背包。第i种物品最多有Mi件可用&#xff0c;每件耗费的空间为Ci&#xff0c;价值为Wi。求解将哪些物品装入背包可使得这些物品耗费的空间总和不超过背包容量&#xff0c;且价值总和最大。 将Mi件摊开&#xff0c;就是一个01背…

CocoaAsyncSocket 套接字

CocoaAsyncSocket 套接字 https://github.com/robbiehanson/CocoaAsyncSocket Asynchronous socket networking library for Mac and iOS 用于iOS以及Mac的异步套接字网络库。 TCP GCDAsyncSocket and AsyncSocket are TCP/IP socket networking libraries. Here are the key…

谷歌浏览器设置缓存方法

谷歌浏览器设置缓存方法&#xff1a; 1、在桌面Google Chrome快捷方式&#xff0c;目标&#xff1a;找到 C:\Users\Splendid\AppData\Local\…\Application\chrome.exe 在这后面加上-Disk-Cache-Dir”Z:\TEMP” 注意: -Disk前面有空格&#xff0c;”Z:\TEMP” 是文件存放在Z盘T…

《dp补卡——子序列问题》

目录300. 最长递增子序列674. 最长连续递增序列718. 最长重复子数组1143. 最长公共子序列53. 最大子序和392. 判断子序列115. 不同的子序列583. 两个字符串的删除操作72. 编辑距离647. 回文子串 &#xff08;与 5.最长回文子串思路差不多&#xff09;516. 最长回文子序列300. 最…

《leetcode : 647. 回文子串 思考分析双指针解法》

647. 回文子串 如何确定是回文串&#xff1a; 找中心然后往两边扩散&#xff0c;判断是否对称即可。 在遍历中心点的时候&#xff0c;注意中心点可以是一个元素也可以是两个元素。 class Solution { public:int cal_two_extend(const string& s,int i,int j,int n){int re…