A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 hydee 于 2018-6-21 11:07 编辑

网络爬虫技术

爬虫技术简介
  网络爬虫(Web crawler),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。它们被广泛用于互联网搜索引擎或其他类似网站,可以自动采集所有其能够访问到的页面内容,以获取或更新这些网站的内容和检索方式。从功能上来讲,爬虫一般分为数据采集,处理,储存三个部分。
传统爬虫从一个或若干初始网页的URL开始,获得初始网页上的URL,在抓取网页的过程中,不断从当前页面上抽取新的URL放入队列,直到满足系统的一定停止条件。
聚焦爬虫的工作流程较为复杂,需要根据一定的网页分析算法过滤与主题无关的链接,保留有用的链接并将其放入等待抓取的URL队列。然后,它将根据一定的搜索策略从队列中选择下一步要抓取的网页URL,并重复上述过程,直到达到系统的某一条件时停止。
另外,所有被爬虫抓取的网页将会被系统存贮,进行一定的分析、过滤,并建立索引,以便之后的查询和检索;对于聚焦爬虫来说,这一过程所得到的分析结果还可能对以后的抓取过程给出反馈和指导。

爬虫系统工作原理
  在网络爬虫的系统框架中,主过程由控制器,解析器,资源库三部分组成。控制器的主要工作是负责给多线程中的各个爬虫线程分配工作任务。解析器的主要工作是下载网页,进行页面的处理,主要是将一些JS脚本标签、CSS代码内容、空格字符、HTML标签等内容处理掉,爬虫的基本工作是由解析器完成。资源库是用来存放下载到的网页资源,一般都采用大型的数据库存储,如Oracle数据库,并对其建立索引。

爬虫技术行业应用
  • 搜索引擎聚合了网页:百度,google
  • 机票比价网站:去哪儿,聚合各大航空公司票价
  • 比价网站聚合了各大电商平台的商品价格:美丽说,蘑菇街,一淘
  • 新闻聚合平台:今日头条
  • 招标信息平台:中国采招网、中国采购与招标网、剑鱼招标网



后台爬虫三大问题
1、交互问题
    有些网页往往需要和用户进行一些交互,进而才能走到下一步,比如输入一个验证码,拖动一个滑块,选几个汉字。网站之所以这么做,很多时候都是为了验证访问者到底是人还是机器。而爬虫程序遇到这种情况很难处理,传统的简单图片验证码可以通过图形处理算法读出内容,但是随着各种各样,花样百出的验证码越来越多,这个问题就越来越严重。

2、资源解析问题
  目前大多数网页属于动态网页(内容由javascript动态填充),尤其是在移动端,SPA/PWA应用越来越流行,网页中大多数有用的数据都是通过ajax/fetch动态获取后然后再由js填充到网页dom树中,单纯的html静态页面中有用的数据很少。目前主要应对的方案就是对于js ajax/fetch请求直接请求ajax/fetchurl ,但是还有一些ajax的请求参数会依赖一段javascript动态生成,比如一个请求签名,再比如用户登陆时对密码的加密等等,如果一昧的去用后台脚本去干javascript本来做的事,这就要清楚的理解原网页代码逻辑,而这不仅非常麻烦,而且会使你的爬取代码异常庞大臃肿,但是,更致命的是,有些javascript可以做的事爬虫程序是很难甚至是不能模仿的,比如有些网站使用拖动滑块到某个位置的验证码机制,这就很难再爬虫中去模仿。其实,总结一些,这些弊端归根结底,是因为爬虫程序并非是浏览器,没有javascript解析引擎所致。针对这个问题,目前主要的应对策略就是在爬虫中引入Javascript 引擎,如PhantomJS,但是又有着明显的弊端,如服务器同时有多个爬取任务时,资源占用太大。还有就是,这些 无窗口的javascript引擎很多时候使用起来并不能像在浏览器环境中一样,页面内部发生跳转时,会导致流程很难控制。

3、IP限制问题
  这是目前对后台爬虫中最致命的。网站的防火墙会对某个固定ip在某段时间内请求的次数做限制,如果没有超过上线则正常返回数据,超过了,则拒绝请求,如qq 邮箱。值得说明的是,ip限制有时并非是专门为了针对爬虫的,而大多数时候是出于网站安全原因针对DOS攻击的防御措施。后台爬取时机器和ip有限,很容易达到上线而导致请求被拒绝。目前主要的应对方案是使用代理,这样一来ip的数量就会多一些,但代理ip依然有限,对于这个问题,根本不可能彻底解决。


数据抓取案例
[Java] 纯文本查看 复制代码
        @Test
        public void getInfo() throws Exception{
                //下载网页内容
                String html = NetUtil.downloadString("http://www.gd-n-tax.gov.cn/pub/gzsgsww/xxgk/tzgg/gstg/index.html");
                //创建解析对象
                Jerry doc = Jerry.jerry(html);
                //创建日期处理对象
                DateFormat df = DateFormat.getDateInstance();
                //使用选择器获取需要的资源,此处获取标题块的的每个li标签
                doc.$(".tab_con_main.box ul li").each(new JerryFunction() {
                        
                        @Override
                        public Boolean onNode(Jerry $this, int index) {
                                try {
                                        
                                        //抓取通告标题
                                        String title = $this.$("a").text();
                                        //抓取创建日期
                                        String createTime = $this.$(".date").text();
                                        //------------------获取a标签链接地址并发送请求抓取通知内容-----------
                                        String url = $this.$("a").attr("href").replace("./", "http://www.gd-n-tax.gov.cn/pub/gzsgsww/xxgk/tzgg/gstg/");
                                        Jerry doc = Jerry.jerry(NetUtil.downloadString(url));
                                        //获取class样式为TRS_Editor的所有p标签,包括每个p标签里的html内容
                                         String content = doc.$(".TRS_Editor p").htmlAll(true);
                                        
                                        System.out.println("通告标题:"+title);
                                        System.out.println("发布时间:"+createTime);
                                        System.out.println("通告内容:"+content);
                                } catch (Exception e) {
                                        e.printStackTrace();
                                }
                                System.out.println("数据抓取完成");
                                return true;
                        }
                });
        }


0 个回复

您需要登录后才可以回帖 登录 | 加入黑马