Python爬虫技术与应用:网络爬虫概述

Python爬虫技术与应用:网络爬虫概述

1.1 网络爬虫简介

1.1.1 网络爬虫的概念与类别

1.概念

当前社会已经迈入大数据时代,互联网中的数据是海量的,如何自动高效地获取互联网中有用的信息是一个重要问题,而网络爬虫技术就是为解决这些问题而生的。

当下的网络就像一张大型的蜘蛛网,分布于蜘蛛网各个节点的即是数据,那么Web Crawler(网络爬虫)即是小蜘蛛,沿着网络“捕获”食物(即数据),而网络爬虫是指按照一定的规则,自动地抓取网络信息的程序或者脚本。从专业角度来讲,请求目标的行为是经由程序模仿搜索引擎发出的,爬到本地的是目标返回的HTML代码、JSON数据、二进制数据、图片、视频等,从中提取需要的数据并存储起来使用。

2.常见的网络爬虫

搜索引擎如何获得一个新网站的URL?主要描述如下:

(1)主动向搜索引擎提交网站。

(2)在其网站里设置外联。

(3)搜索引擎会和DNS服务商进行合作,能够快速采集新的网站。

常见的网络爬虫有以下几种。

· 通用网络爬虫:也叫全网爬虫,主要为门户网站站点搜索引擎和大型Web服务提供商采集网络数据。

通用网络爬虫并不是一切皆可爬取,它也要遵循Robots协议。通用网络爬虫的工作流程为:抓取网页→存储数据→内容处理→提供检索→排名服务。

通用网络爬虫的缺点有:仅提供与文本相关的内容(如HTML、Word、PDF等),而无法提供多媒体文件(如音乐、图片、视频)和二进制文件,提供的结果一成不变,无法针对不同背景领域的人提供不同的搜索结果,不能提供人类语义上的检索;具有局限性,所返回的网页里90%的内容无用,中文搜索引擎的自然语言检索理解困难,信息占有量和覆盖率存在局限,以关键字搜索为主是搜索引擎最主要的作用之一,对于图片、数据库、音频、视频多媒体的内容无计可施;搜索引擎的社区化和个性化欠缺,大多数搜索引擎无法考虑人的地域、性别、年龄的差别,且抓取动态网页效果不好。

· 聚焦网络爬虫:网络爬虫程序员写的针对某种内容的网络爬虫,面向主题网络爬虫、面向需求网络爬虫,会针对某种特定的内容去抓取信息,并且保证内容需求尽可能相关。聚焦网络爬虫是为解决通用网络爬虫的缺点而出现的。

· 积累式网络爬虫:从头到尾,不断抓取,过程中会进行反复操作。

· 增量式网络爬虫:采用增量式更新和仅抓取新产生的或者已经发生变化的网页的网络爬虫,出现在已下载的网页。

· 深层网络爬虫:Web页面按存在方式可以分为表层网页(Surface Web)和深层网页(Deep Web)。表层网页是指传统搜索引擎可以索引的页面,以超链接可以到达的静态网页为主构成的Web页面。深层网页是指那些大部分内容不能通过静态链接获取的、隐藏在搜索表单后的,只有用户提交一些关键词才能获得的Web页面。

3.增量式网络爬虫

增量式网络爬虫(Incremental Web Crawler)的体系结构包括爬行模块、排序模块、更新模块、本地页面集、待爬行URL集及本地页面URL集。

增量式网络爬虫为确保本地页面集中存储的页面是最新页面并进一步提高本地页面集中页面的质量,经常使用的方法有:

(1)统一更新法:网络爬虫以相同的频率访问全部网页,不考虑网页的改变频率。

(2)个体更新法:网络爬虫按照个体网页的改变的频率重新访问各页面。

(3)基于分类的更新法:网络爬虫根据网页改变的频率把页面划分为更新较快网页子集和更新较慢网页子集两类,而后以不同的频率访问这两类网页。

为实现个体更新法,增量式网络爬虫需要对网页的重要性排序,一般常用的策略有广度优先策略、PageRank优先策略等。IBM开发的WebFountain增量式网络爬虫功能强大,它采用一个优化模型控制爬行过程,并没有对页面变动过程做一概统计假设,而是按照先前爬行周期里的爬行成果和网页的实际变化速度对页面的更新频率进行调整,采用的是一种自适应的方法。北京大学的天网增量爬行系统的目的是爬行国内Web,把网页划分为变化网页和新网页两类,分别采用不同爬行策略。为减缓对大量网页变化历史维护导致的性能难题,它按照网页变化的时间局部性规律,在短时期内直接爬行屡次变化的网页,为尽快取得新网页,它操纵索引型网页追踪新出现的网页。

4.深层网络爬虫

1)基于领域知识的表单填写

此方式一般会维持一个本体库,经由语义分析来选取合适的关键词填写表单。利用一个预定义的领域本体知识库来识别深层网页的页面内容,同时利用一些来自Web站点的导航模式来辨认主动填写表单时所需进行的路径导航。

2)基于网页结构分析的表单填写

此方式通常无领域知识或有唯一有限的领域知识,把网页表单表示成DOM树,从中提取表单各字段值。Desouky等提出一种LEHW方法。该方法把HTML网页表示为DOM树形式,把表单区分为单属性表单和多属性表单,分别进行处理;孙彬等提出一种基于XQuery的搜索系统,它能够模拟表单和特殊页面的标记切换,把网页关键字切换信息描述为三元组单元,依照一定规则排除无效表单,把Web文档构造成DOM树,利用XQuery把文字属性映射到表单字段。

1.1.2 网络爬虫的流程

1.基本流程

捜索引擎抓取系统的主要组成部分是网络爬虫,把互联网上的网页下载到本地形成一个联网内容的镜像备份是网络爬虫的主要目标。

网络爬虫的基本工作流程如下:一开始选取一部分精心挑选的种子URL;把这些URL放入URL队列中;从URL队列中取出待抓取的URL,读取URL之后开始解析DNS,并把URL对应的网页下载下来,放进网页库中。此外,把这些URL放入已抓取URL队列。

分析已抓取URL队列中的URL,并且把URL放入待抓取URL队列,使其进入下一个循环。网络爬虫的基本流程如图1-1所示。

在这里插入图片描述

用简短易懂的方式来讲,即分为四个步骤:发送请求→获取响应内容→解析内容→保存数据。请求流程如图1-2所示。

在这里插入图片描述

2.从网络爬虫的角度对互联网进行划分

从网络爬虫的角度可将互联网划分为以下五种:

(1)已下载未过期网页。

(2)已下载已过期网页:抓取到的网页实际上是互联网内容的一个镜像与备份,互联网是动态变化的,一部分互联网上的内容已经发生变化,这时这部分抓取到的网页就已经失效。

(3)待下载网页:是指待抓取URL队列中的那些页面。

(4)可知网页:尚未抓取下来,也没有在待抓取URL队列中,但是能够经由对已抓取页面或者待抓取URL对应页面进行分析获得的URL,认为是可知网页。

(5)不可知网页:还有一部分网页,网络爬虫是无法直接抓取下载的,称为不可知网页。

网页类别划分如图1-3所示。

3.网页抓取的基本原理

常见的叫法是网页抓屏(Screen Scraping)、数据挖掘(Data Mining)、网络收割(Web Harvesting)或其类似的叫法。

理论上,网页抓取是一种经由多种方法收集网络数据的方式,不仅是经由与API交互的方式。

最常用的方法是确定爬取的URL,确定数据存储格式,写一个自动化程序向网络服务器请求数据(通常是用HTML表单或其网页文件),而后对数据进行清洗解析,汲取需要的信息并存入数据库,基本思路如图1-4所示。

在这里插入图片描述

在这里插入图片描述

4.目标源选择

目标源选择应依照以下条件进行排序:数据相关性、易抓取程度、数据量、Robots协议。当然,根据自己的需求能够自由变更。同等情况下尽量避免大型企业的官网,因为其中大部分都设有反爬机制。

5.编辑网络爬虫

推荐使用的库有requests、BeautifulSoup、Scrapy、Selenium,假如关于效率需求不是特别高,能够考虑使用requestspost请求采集页面,而后使用BeautifulSoup分析页面标签,这样实现较为简短易懂,也能解决大部分需求;假如对效率比较重视,或需要完成一个工程化的采集项目,Scrapy能够作为首选。对分布式处理的良好支持和清晰的模块化层次在提升效率的同时更易于进行代码的管理。对HTTP的相关请求,使用requests比用其他函数更加明智。

6.数据清洗

获得的数据和期望中的数据总有一定的差别,这一部分的任务便是排除异常数据,把其余数据转换为易于处理的形式。数据的异常主要包括数据格式异常和数据内容异常。需要的数据可能存放在一个PDF、Word、JPG格式的文件中,把它们转换成文本而后选取相应的信息,这是数据清洗工作的一部分。另外,由于网页发布者的疏忽,网页上有部分数据和其他页面呈现不同,但需要把这部分数据也抓取下来,此时需要进行一定的处理,把数据格式进行统一。

1.1.3 网络爬虫的抓取

1.概述

网络爬虫的不同抓取策略,便是利用不同的方法确定待抓取URL队列中URL的优先顺序。网络爬虫的抓取策略有很多种,但不管方法如何,其根本目标一致。网页的重要性评判标准不同,大部分采用网页的流行性进行定义。网页结构分布图如图1-5所示。

在这里插入图片描述

2.网络爬虫的抓取原理

一开始选取一部分精心挑选的种子URL,把这些URL放入待抓取URL队列,从待抓取URL队列中拿出待抓取的URL,解析DNS并且得到主机的IP地址,并把URL相应的网页下载下来,存放进已下载网页库中。此外,把这些URL放进已抓取URL队列。分析已抓取URL队列中的URL,分析当中的其他URL,并且把URL放入待抓取URL队列,继续进入下一个循环。

3.网络爬虫的抓取策略

1)宽度优先遍历(Breath First)策略

基本思路:将新下载网页包含的链接直接追加到待抓取URL队列末尾。

倘若网页是1号网页,从1号网页中抽取出3个链接指向2号、3号和4号网页,于是按照编号顺序依次放入待抓取URL队列,图中网页的编号便是在待抓取URL队列中的顺序编号,之后网络爬虫以此顺序进行下载。抓取节点树结构如图1-6所示。

2)非完全PageRank(Partial PageRank)策略

基本思路:对于已下载的网页,加上待抓取URL队列中的URL一起,形成网页集合,在此集合内进行PageRank计算,计算完成后,把待抓取URL队列里的网页依照PageRank得分由高到低排序,形成的序列便是网络爬虫接下来应该依次抓取的URL列表。

设定每下载3个网页进行新的PageRank计算,此时已经有{1,2,3}3个网页下载到本地。这三个网页包含的链接指向{4,5,6},即待抓取URL队列,如何决定下载顺序?将这6个网页形成新的集合,对这个集合计算PageRank的值,这样4、5、6就获得对应的PageRank值,由大到小排序,即可得出下载顺序。假设顺序为5、4、6,当下载5号页面后抽取出链接,指向页面8,此时赋予8临时PageRank值,如果这个值大于4和6的PageRank值,则接下来优先下载页面8,如此不断循环,即形成非完全PageRank策略的计算思路。非完全PageRank策略结构图如图1-7所示。

在这里插入图片描述

在这里插入图片描述

3)OPIC(Online Page Importance Computation,在线页面重要性计算)策略

基本思路:在算法开始之前,每个互联网页面都给予相同的“现金”,每当下载某个页面后,此页面就把本身具有的“现金”平均分配给页面中包含的链接页面,把本身的“现金”清空。与PageRank的不同在于:PageRank每次需要迭代计算,而OPIC策略不需要迭代过程。所以,OPIC的计算速度远远快于PageRank,适合实时计算使用。

4)大站优先(Larger Sites First)策略

基本思路:以网站为单位来选题网页重要性,关于待抓取URL队列中的网页,按照所属网站归类,假如哪个网站等待下载的页面最多,则优先下载这些链接,其本质思想倾向于优先下载大型网站,因为大型网站常常包括更多的页面。鉴于大型网站往往是著名企业的内容,其网页质量一般较高,所以这个思路虽然简单,但是有可靠依据。实验表明,这个算法结果也要略优先于宽度优先遍历策略。

1.2 网络爬虫的攻防战

网络爬虫是模仿人的浏览访问行为,进行数据的批量抓取。当抓取数据量慢慢增大时,会对被访问的服务器造成很大的压力,甚至有可能会崩溃。服务器第一种识别网络爬虫的方式便是经由检查连接的用户代理(User-Agent)来识别到底是浏览器访问,还是代码访问。假如是代码访问,当访问量增大时,服务器就会直接封掉来访IP地址。

在进行访问时,在开发者环境下不仅能够找到URL、FormData,还能够在requests传入headers中构造浏览器的请求头封装,只需要构造这个请求头的参数,创建请求头部信息便可,代码如下:

    import requests
    headers = {
         'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/74.0.3729.157
Safari/537.36',
    }
    #经由requests()方法构造一个请求对象
    url = r'https://www.baidu.com//'
    response = requests.get(url, headers = headers)

很多人会认为修改User-Agent太简短易懂,确实很简短易懂,但正常人一秒看一张图,而网络爬虫一秒能看几百张图,那么服务器的压力必然增大。也就是说,假如在一个IP地址下批量访问下载图片,这个行为不符合正常人类的行为,肯定会被限制。其原理也很简单易懂,便是统计每个IP地址的访问频率,此频率超过阈值,就会返回一个验证码,假如真的是用户访问,用户就会填写,而后继续访问,假如是代码访问,就会被限制。

这个问题的解决方法有两个,第一个便是常用的增设延时,每三秒抓取一次,代码如下:

import time
time.sleep(3)

其实,还有一个更重要的方法,那便是从本质解决问题。不管如何访问,服务器的目的都是查出哪些为代码访问,而后加以限制。解决办法如下:为以防无法访问,在数据采集之前经常会使用代理,可以通过设置requests的proxies属性的方式实现。

首先构建自己的代理IP地址池,把其以字典的形式赋值给proxies,而后传输给requests,代码如下:

proxies = {
   "http":"http://10.10.1.10:3128",
   "https":"http://10.10.1.10:1080",
}
response = requests.get(url,proxies=proxies)

1.3 反网络爬虫技术及解决方案

1.网络爬虫的危害

1)网络爬虫的影响

性能骚扰:Web服务器默认接收人类访问,受限于编辑水平和目的,网络爬虫将会为Web服务器带来巨大的资源开销。

法律风险:服务器上的数据有产权归属,网络爬虫获取数据后牟利将带来法律风险。

2)侵犯用户隐私和知识产权

互联网用户的隐私、公司的商业机密,在大数据时代极易被网络爬虫窃取,相关的网络安全技术人员得采用必要的手段反爬,例如cookie反爬机制等,避免因商业机密的泄露而造成的经济损失。

客户端向服务器发送请求,请求头里面携带cookie信息,服务器检查cookie时效,如果cookie没有过期,则返回响应的请求数据。携带cookie发送请求如图1-8所示。

在这里插入图片描述

2.反爬技术

1)验证码(Verification Code)

验证码是一种直接而有效的方式,用来判断请求方是否是人类。从一开始的简短易懂数字验证码,到后来的中文验证码,再到现在的图片验证码,验证码是应用层最普遍、最核心的网络爬虫对抗技术。关于一些简短易懂的数字、字母验证码,随着近几年机器学习、神经网络的快速发展,已经近乎于失效。有人训练出基于LSTM的模型能够达到90%的识别正确率。关于图片验证码,也有专门用人工打码平台来处理,所以仅靠验证码很难有效处理网络爬虫问题,过多的验证码也会使正常用户的体验受到影响。简单验证码如图1-9所示。

在这里插入图片描述

2)Ajax

Ajax技术在2004年左右开始飞速发展,成为主流的浏览器端技术,也使得网络爬虫从静态网络爬虫转化为动态网络爬虫。至此,抓取网站的数据不再是简短易懂的一个HTTP请求,解析HTML页面就能够实现的。大量的网站使用Ajax技术来构建网站,也使得解析数据变得相对没那么容易获取,因为在网站完全不设防的情况下,网络爬虫也不单需要解析HTML页面,同时还需要解析Ajax接口返回的数据,代码如下:

function get(){
    $.ajax({
       type:"OPTIONS",
       url:"/",
       compelete:function(d){
          var t = d.getResponseHeader("Date");
          var timestamp = Date.parse(t);
          var times = timestamp/1000;
          var dateNow = formateDate(new Date(timestamp));
          liveNow(dateNow,times);
       }
    });
};

3)数据混淆

网络爬虫的目标是抓取到有用的数据。对于许多应用来说,获取错误的数据往往比获取不到数据更加致命。这个思路的核心便是,当网络爬虫命中反爬规则之后,使用错误的数据取代正确的数据返回给网络爬虫,这种方式十分隐蔽,又能够对敌手造成足够的麻烦,也相当有效。

4)经由User-Agent控制访问

不管是浏览器还是网络爬虫程序,在向服务器发起网络请求时,都会发过去一个头文件headers,就像百度的请求头,大多数的字段都是浏览器向服务器表明身份用的,对于网络爬虫程序来说,最需要注意的字段便是User-Agent。很多网站都会创建User-Agent白名单,只有属于正常范围的User-Agent才能够正常访问,代码如下:

 #导入requests库
    import requests
    #定义获得URL的函数
    def get_html(url):
        try:
           #请求获得URL,超时时间30s
         r=requests.get(url,timeout=30)
           #状态响应
         r.raise_for_status()
           #转换成UTF-8的编码格式
         r.encoding = r.apparent_encoding
           #返回响应的文本数据
         return r.text
        except:
           #运行错误返回值
            return "Something Wrong!"
    #输出获得URL
    print(get_html('https://www.baidu.com'))

5)经由IP地址限制反网络爬虫

假如一个固定的IP地址在短暂的时间内快速大量地访问一个网站,那么自然会引起注意。管理员能够经由一些手段禁止该IP地址访问,网络爬虫程序则无法工作。

解决方法:比较成熟的方式是IP地址代理池,简而言之,便是经由IP地址代理,从不同的IP地址进行访问,这样就无法限制该IP地址的访问。但是IP地址代理的获得本身便是一个很麻烦的事情,虽然网上有免费和付费的,但是质量参差不齐。假如是企业需要,能够经由自己购买集群云服务来自建代理池。这里实现一个简短易懂的代理转换,代码如下:

 import random
    def get_proxy():
        '''
        简答模拟代理池
        返回一个字典类型的键值对,
    '''
        proxy = ["http://116.211.143.11:80",
                 "http://183.1.86.235:8118",
                 "http://183.32.88.244:808",
                 "http://121.40.42.35:9999",
                 "http://222.94.148.210:808"]
        fakepxs = {}
        fakepxs['http'] = proxy[random.randint(0, len(proxy)-1)]
        return fakepxs

6)经由Robots协议限制网络爬虫

世界上将网络爬虫做得最大、最好的便是Google。搜索引擎本身便是一个超级大的网络爬虫,Google开发出来的网络爬虫24小时不中断地在网上抓取着新的信息,并返回给数据库,但是这些搜索引擎的网络爬虫都遵循着Robots协议。

Robots协议是一种寄放于网站根目录下的ASCII编码的文本文件,它往往通知网络搜索引擎的漫游器,该网站中的哪些内容是不应被搜索引擎的漫游器获得的,哪些是能够被漫游器获得的。

Robots协议并不是一个标准,而只是约定俗成的,所以并不能保护网站的隐私。注意,Robots协议是用字符串比较来确定是否获得URL,所以目录结尾有与没有斜杠“/”表示的是不同的URL。Robots协议允许使用类似’Disallow:*.gif '这样的通配符。

这实际上只是一个自由协议,遵循与否,都在于网络爬虫的编辑者。来看一下京东的Robots协议,代码如下:

User-agent: *
Disallow: /?*
Disallow: /pop/*.html
Disallow: /pinpai/*.html?*
User-agent: EtaoSpider
Disallow: /
User-agent: HuihuiSpider
Disallow: /
User-agent: GwdangSpider
Disallow: /
User-agent: WochachaSpider
Disallow: /

能够看到,京东的Robots协议里确定地指出四个“User-Agent”是禁止访问的,事实上,这四个User-Agent也是四个臭名远扬的恶性网络爬虫。当然有种情况是例外的,例如网络爬虫获得网页的速度和人类浏览网页是差不多的,这并不会给服务器造成太大的性能损失,在这种情况下是可以不用遵守Robots协议的。
在这里插入图片描述

  • 6
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值