网络爬虫的设计与实现_第1页
网络爬虫的设计与实现_第2页
网络爬虫的设计与实现_第3页
网络爬虫的设计与实现_第4页
网络爬虫的设计与实现_第5页
已阅读5页,还剩35页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

网络爬虫的设计与实现到自己期待的数据,这样靠人搜索复制粘贴出来的数据就会对后面的数据分析的结果就会出行偏差。网络爬虫就很好的解决了这个问题。1.2国内外研究现状目前大多数网页属于动态网页(内容由javascript动态填充),尤其是在移动端,SPA/PWA应用越来越流行,网页中大多数有用的数据都是通过ajax/fetch动态获取后然后再由js填充到网页dom树中,单纯的html静态页面中有用的数据很少。网站的防火墙会对某个固定ip在某段时间内请求的次数做限制。后台爬取时机器和ip有限,很容易达到上线而导致请求被拒绝。有些网页往往需要和用户进行一些交互,进而才能走到下一步,比如输入一个验证码,拖动一个滑块,选几个汉字。网站之所以这么做,很多时候都是为了验证访问者到底是人还是机器。现在国内外对爬虫的研究主要是如何解决人机交互,解决JavaScript的解析和IP限制的问题。快速的提取到用户所需的数据,提取动态页面的数据,使用代理突破IP限制的问题。1.3本文的研究内容与主要内容本文通过使用scrapy框架实现部署分布式爬虫爬取智联招聘网站整站的内容,将爬去得到的内容存入到redis数据中。主要的研究方向是如何快速高效的实现部署分布式爬虫爬取爬取网页信息。使用re正则表达式来匹配新产生的URL,用Xpath来解析网页的内容,将解析出的数据存储到redis数据库中。实现分布式爬虫的部署,通过增量式爬虫得到新的URL,多台电脑同时运行,可以使得爬虫更快更加高效,单机的网络爬虫有CPU,IO,带宽等多重限制,部署成分布式爬虫就可以水平扩展,单机的性能不过增加机器就可以解决CPU,IO,带宽等带来的限制。通过分布式爬虫和增量式爬虫结合,动态爬取智联网站上我们需要的数据,将数据存储到redis数据中。1.4论文的组织结构本文主要根据网络爬虫的特点,使用python语言,scrapy框架设计出进行分布式爬取数据的程序。本文主要分为6个章节结构安排如下。绪论,对课题的背景研究意义和爬虫的研究内容与主要内容就行了简单的介绍。相关技术。对本论文会使用到的一些技术,工作原理进行了简单的介绍。网络爬虫。对网络爬虫的定义,工作的原理进行简单的介绍,引出网络爬虫的相关技术。开发工具。介绍了本网络爬虫的完成中使用到了的相关的工具以及一些配置。网络爬虫的实现,具体了介绍了如何实现该网络爬虫,在实现的过程中解决遇到的问题。代理服务器。具体介绍如何去解决IP禁止的问题,如何自己去搭建代理池和使用代理。总结和展望。对该网路爬虫的事项进行总结以及展望未来。1.5本章小结本章内容介绍了实现网络爬虫的背景以及国内外的研究现状进行了一个简单的介绍。第二章相关技术2.1pythonPython是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言而且python的相当容易维护。python在开发的过程中没有编译的环节,支持面向对象和代码封装和代码继承。python的设计具有很强的可读性,相比其他语言经常使用英文关键字,结构,简单,相比其他语言的一些标点符号,它具有比其他语言更有特色语法结构。python是一种开源的语言,它拥有非常多的库和跨平台,在Linux和Windows和Macintosh中的兼容性都非常好。基于python的开发其源代码的特性,许多平台都移植有python。支持互动模式的编程思想,可以在编程的时候在终端输入执行代码,并且获取到结果,调试代码片段互动的调试,及时对代码作出相应的调试与运行,减少了BUG的产生。许多的系统都支持python的GUI的创建和移植。python的层级结构语法使得阅读代码变得更加简单易懂,关键字也是简明扼要。2.2robots协议robots协议并不是技术层面的协议,是一个文本文件,用于保护使用者的个人信息和隐私,robots协议是一个君子协定。首先在爬取一个网站的时候,第一步就是要访问这个网站的robots.txt文件,这个文件里规定可那些爬虫可以爬取哪些内容,爬虫要严格按照robots.txt文件的要求去爬取网站的相关的内容(让你爬才能爬,其他不能爬),搜索引擎的爬虫必须要遵守协议。我们写爬虫不需要遵守。当网络爬虫访问某个站点时,它会首先检查该站点根目录下是否存在robots.txt,如果存在,搜索引擎读取该文件中的配置信息,这些配置信息决定了爬虫在该站点内所拥有的权限;如果文件不存在,那么搜索引擎爬虫就沿着站点内的所有连接抓取[4]。2.3re正则表达式正则表达式的“鼻祖”或许可一直追溯到科学家对人类神经系统工作原理的早期研究。正则表达式,又称规则表达式。是计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑,使得符合规则就保留下来,在爬虫中对URL的清洗以及过滤有着无可替代的作用。可以在给定的字符串检查是否含有符合正则表达式的过滤逻辑,有就保留,否则就过滤掉。通过这种方法从字符串中获取到我们需要的特定的部分。正则表达式是一种特殊的字符序列,可以帮助方便检查一个字符串是否符合某种匹配模式,在爬虫中匹配URL就需要用到正则表达式,python中用re模块,提供了Perl风格的正则表达式模式,python语言拥有所有的正则表达式的功能。现在正则表达式在基于文本的编辑器和搜索工具中依然占据着一个非常重要的地位。2.4Redis数据库数据库分为关系型数据库(MySQL就是关系型数据库)和非关系型数据库Redis是一个高性能的Key-value数据库,它属于NoSQL数据库(非关系型数据库)。Redis是一种基于内存的高效的键值型非关系型数据库,存取效率极高,使用也非常简单。Redis中存储的数据都是key-value形式的,提供多种语言的API接口,Redis数据库的性能极好。Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启时候可以再次加载进行使用,而且存储的速度极快。Redis不仅仅支持简单的key-redis类型的数据,Redis有丰富的数据类型,提供了list,set,zset,hash等数据结构的存储。Redis支持数据的备份,即master-slave模式的数据备份。支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行。速度快,因为数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1),Redis数据库丰富的特性:可用于缓存,消息,按key设置过期时间,过期后将会自动删除。Reids在内存存储引擎领域的一大优点是提供list和set操作,这使得Redis能作为一个很好的消息队列平台来使用。Redis作为队列使用的操作,就类似于本地程序语言(如Python)对list的push/pop操作。Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。在需要用到redis数据库存储数据前要先在终端运行redis.server命令,将redis数据库打开。打开redis数据库2.5xpathXML是树状结构,类似档案系统内数据夹的结构,是一种XML路径语言,XPath也类似档案系统的路径命名方式,适用于在XML文档中查找信息的语言,适用于HTML的文档的搜索。XPath是一种模式(Pattern),可以选出XML档案中,路径符合某个模式的所有节点出来。用来查找某个特定的节点或者包含某个指定的值的节点,选取想xml中的元素,更深入地提炼所选的节点集。Xpath的选择功能十分强大,提供了非常简单明了的路径选择表达式,几乎能定位到所有我们需要的节点。可以用于字符串、数值、时间的匹配以及节点、序列的处理等。XPath表达式可返回节点集、字符串、逻辑值以及数字。xpath库是用于网页的解析,XPath是XML的路径语言,通俗一点讲就是通过元素的路径来查找到这个标签元素,默认先写//*代表定位页面下所有元素。Xpath支持ID、Class、Name定位功能还支持属性定位的功能,用@代表以属性定位,后面可以接标签中任意属性。当标签的属性重复时,Xpath提供了通过标签来进行过滤,将*换位任意标签名,就可根据标签进行筛选。xpath还提供了层级过滤,支持通过/进行层级递进,找到符合层级关系的标签。一个元素它的兄弟元素跟它的标签一样,这时候无法通过层级定位到。。Xpath提供了索引过滤和逻辑运算(add或or)。相对于正则表达式,xpath对提取网页上的页面的内容会显得更加简单易懂快捷,使得爬虫提取网页上的信息内容会方便很多,节省了编程过程中因匹配所消耗的时间。在页面信息提取的时候如果使用的是正则表达式,会比较繁琐,万一有一个地方写错了,可能就导致匹配失败,使用正则表达式提取页面的信息会有些不方便。2.6Scrapy框架Scrapy是一个基于Twisted的异步处理框架,是纯python实现的爬虫框架,器架构清晰,模块之间的耦合度低,可扩展性强,可以灵活完成各种需求。Scrapy功能非常强大,爬取的效率高,相关的扩展的组件多,可配置和扩展程度非常高,几乎能应对所有的网站的爬取,是目前python中使用的最广泛的爬虫框架。Scrapy框架可以分为以下的几个部分:Englie(引擎),是这个框架的核心,负责处理整个系统的数据流在组件中的流动,并在相应的动作发生时触发事务。Item(项目),定义了爬取结果的数据结构,爬取出来的数据都会赋值给这个Item的对象。Scheduler(调度器),它接受引擎发过来的请求并将这些请求放入到队列之中,在引擎再次请求的时候就将这些请求提供给引擎。Downloader(下载器),下载用户定义好的网页内容,并且将网页的内容返回给spiders。spiders(蜘蛛),用户在这里定义了要爬取的网页的逻辑和网页的解析规则,主要是负责解析响应并生成提取所需的结果和新的请求(URL)。ItemPipeline是项目的管道,负责处理spider从网页上提取出来的项目,主要的任务就是清洗、过滤和存储数据流,处理被spider提取出来的item,进行验证,清理以及持久化等。DownloaderMiddlewares是下载的中间件,是位于引擎和下载器之间的钩子框架,下载中间件的作用是处理引擎与下载器之间的发起的请求和响应的过程,处理下载器传递给引擎的Response。SpiderMiddlewares叫做蜘蛛中间件,主要处理spider输入的响应和输出的结果以及新的请求,发送items给ItemPipline和发送Request给调度器。InternetSchedulerInternetSchedulerScrapyEngineResquestsResquestsScrapyEngineDownloaderItemPipelineDownloaderMiddlewaresDownloaderItemPipelineItemsResponsesspiderspiders图3-1Scrapy构架scrapy中的数据流由引擎决定,引擎首先打开一个网站,找到并处理这个网站的spider,并且将该spider请求需要爬取的URL。引擎从spider中获取到第一个需要爬取的URL,在调度器中以Request的形式进行调度。引擎再向调度器请求下一个需要爬取的UPL。调度器会返回下一个需要爬取的URL给引擎,引擎通过将URL把下载中间件转发给下载器进行下载。下载器完成下载以后,下载器生成这个页面的请求,并且通过下载中间件发送给引擎。引擎从下载器那里收到请求以后将它通过spider的中间件转发给spider进行处理。spider处理完请求以后,会得到新的item以及新的请求给引擎,引擎将spider返回的item交给item的中间件,将新的请求发给引擎,引擎将spide那里返回的item发送给item的项目管道,并且将新的请求发送给引擎,直到调度器那里没有请求,引擎就会关闭该网站,爬取网站就到此结束。Scrapy框架是通过多个组件之间的相互协作不同的组件完成的工作不同、组件对异步处理的支持,Scrapy最大限度地利用了网络宽带,大大提高了数据爬取和处理的效率。2.7Requestsrequests库是一个非常好用的HTTP请求库,可用于网络请求和网络爬虫。爬虫最基本的就是模拟浏览器向服务器发起请求的,Requests库是python中用来处理请求的库。不用知道请求的数据的结构是如何实现的的也不用了解HTTP、TCP、IP层的网络传输通信,不需要知道服务器的响应和应答的原理也能进行发起请求。只需要请求的链接和需要传递的参数是什么就可以完成一个请求和响应的处理过程,得到网页的内容。用来模拟发送请求,方便实现请求的发送和得到响应。实现Cookies、登录验证和代理设置等操作。浏览器将对目标位置所在的服务器发起请求Resquest,服务器则响应该请求,将网页以特定的格式Response返回给浏览器,浏览器解析Response并把网页显示到页面上[5]。2.8本章小结本章内容介绍了实现网络爬虫中所需要的一些库和开发的框架,以便于后面这些库和框架实现爬取网页的深刻理解。第三章网络爬虫3.1网络爬虫的历史在互联网发展的初期,网站的数量相对比较少,信息的查找也会比较容易,然而随着万维网的爆炸式快速增长,网站的数量也飞速增长,互联网上的数据量也在爆炸式增长,普通用户想获取到自己所需要的信息如同大海捞针一般,就是一个难字。这是能满足大众信息检索需求的专业检索网站就出现在了大众的眼前了。在90年代开始就有搜索引擎网站利用爬虫的技术抓取网站,搜索引擎实质就是一个web系统,给用户提供一个检索平台。通过爬虫按照互联网的拓扑结构,进行批量的数据抓取,然后进行数据的清洗和整合,然后按照一定的次序存入到数据库的集群中。传统的爬虫从一个或者若干个初始网页的URL开始,获得初始网页的URL,在抓取网页的过程中,不断地从网页上获得新的URL,然后放入到队列之中,直到满足程序的要求的停止条件为止。抓取的URL队列为空,说明爬虫已经将该站的所有页面全部爬取,完成了工作[1]。3.2网络爬虫的分类网络爬虫又被称为网页蜘蛛、网络机器人等,网络爬虫是一种按照一定的规则自动的去抓取互联网信息的程序或者脚本。为搜索引擎从互联网上上面下载网页,是搜索引擎必不可少的一部分。爬虫可以分为通用爬虫和聚焦爬虫和通用爬虫。聚焦爬虫的工作流程是根据网页分析算法过滤出于主题无关的链接,保留有用的链接并将其URL放入到等待抓取的队列之中,所有的被抓取得网页将会被系统存储,根据主题进行分析,过滤。聚焦爬虫在实施网页抓取时会对其内容进行筛选处理,尽量保证只抓取与需求相关的网页信息。也正是如此,聚焦爬虫技术得到了广泛的使用。定向抓取和高度自由为特点的聚焦爬虫成为了开发热点[2]。通用爬虫是搜索引擎抓取系统的重要组成部分,主要是将互联网上的网页下载到本地,通过爬虫按照互联网的拓扑结构,进行批量的数据抓取,然后进行数据的清洗和整合,然后按照一定的次序存入到数据库的集群中。从互联网中收集网页,采集信息,为搜索引擎建立索引从而提供支持。通用搜索引擎大多数提供基于关键字的检索,难以支持根据语义信息提出的查询,无法理解用户的具体的需求。通用搜索引擎偏爱BFS及DFS策略,因为目标相似,都是索引越多越好[3]。3.3网络爬虫的应用对于爬虫而言,数据分析以及机器学习主要负责处理数据,对于一些大公司如腾讯,阿里,百度,它们每天都有海量的数据,每天需要处理的数据的非常庞大的。像这样的BAT公司也需要爬虫,平台越大,需要的第三方的数据量也就越多,对数据的需求就越多。这些数据一方面来源于平台自身数据的生态环境,如腾讯的一些自身的用户,每一个用户访问的时候都会提供数据。一方面来源于第三方网站的数据。如阿里旗下的淘宝和天猫,每天都会有海量的数据产生,但是它也需要一些知名的电商平台的数据。这些公司需要这些数据有什么作用?根据这些数据进行数据的相关特征的提取,分析以及后期人工智能的训练和预测。可以做的事情就相当的多了。特别对于电商和金融对于数据是特别敏感的,电商在推广自己的产品的时候,需要在市场中调研当前比较流行的款式,热销品牌有什么,评论是怎么样,评价是怎么样,正面的评价是怎么样的,负面的评价又是怎么样的,评价的关键字是什么,有什么优缺点,它们的价位又是怎么样的。它们需要对这些数据进行整合和分析,来决定公司的下一步的用户战略,所以爬虫的工作是十分重要的,起到了一个承上启下的作用,对接了web和数据分析。3.4网络爬虫的发展趋势传统的网络爬虫技术主要是用于抓取静态的web页面,随着动态网页的流行,怎么样抓取动态页面成了网络爬虫急需解决的问题,ATAX中不再是传统的HTTP请求/响应协议机制,传统的网络技术是无法抓取到动态页面的有效数据的,需要导入selenium库模拟浏览器才能抓取到动态网页的数据,且传统的网络爬虫以单机爬虫为主,即单点部署,只能单机操作,部署分布式爬虫,可以理解为集群爬虫,如果有spider,可以用多台机器同时运行可以使得网络爬虫更加高效地爬取到我们需要的信息。如何快速效地抓取到动态网页的数据成为了网络爬虫的发展趋势。第四章开发工具4.1操作系统本爬虫程序开发环境是Windows10专业版操作系统,该操作系统是给IBM机器设计的MS-DOS的基础上设计的图形操作系统,支持网页服务和数据库服务功能。是一个支持多用户,多任务、支持多线程和多CPU的操作系统,是一个性能稳定的操作系统。4.2软件配置4.2.1Pycharm介绍在Windows10专业版中,本文主要用的开发软件是PyCharm。PyCharm是由JetBrains打造的一款PythonIDE,PyCharm拥有一般IDE具备的功能,比如,调试、语法高亮、Project管理、代码跳转、智能提示、自动完成、单元测试、版本控制,非常适合python开发使用。4.2.2安装ScrapyScrapy是一个爬虫框架,提取结构性的数据。其可以应用在数据挖掘,信息处理等方面。提供了许多的爬虫的基类,可以帮我们更简便使用爬虫。基于Twisted。安装Scrapy之前首先要要安装符合python版本和系统的版本的Twisted。查看python是多少位的,使用cmd命令打开终端,输入python命令,进入到python的shell终端,在这里就能查看python的版本。查看python的版本查看完python的版本,就安装符合python版本和系统的版本的Twisted,使用pipinstall命令安装。图4-1安装Twisted安装完Twisted后,就安装Scrapy框架。使用pipinstallScrapy命令。注意的是路径名不能有中文,不能用管理员进入cmd,电脑系统用户路径不能是中文。图4-2安装scrapy框架在终端中安装完Scrapy框架以后,要检查Scrapy框架是否安装成功,使用scrapy命令检查。检查scrapy框架是否安装成功可以调出命令,说明scrapy框架安装成功。第五章网络爬虫的实现5.1爬虫的定义网络爬虫是一个非常强大的自动提取Web网页的应用程序,它为搜索引擎从互联网上下载Web页面,是搜索引擎的重要组成部分[1]。爬虫又称为蜘蛛,是一种按照一定的规则,自动地从互联网上抓取用户所需的脚本或程序。即是用户端计算机请求服务器,将服务器中的数据下载到本地的过程爬虫分为三部分:请求、解析、存储。模拟浏览器向服务器发起请求,解析页面,只提取用户所需的信息,将下载好的数据存储到数据库中。爬虫开始运行之后将调度URL,解析并通过服务器获得对应的IP地址[6]。实现一个好的链接价值的计算方法,是聚焦爬虫的关键[7]。HTTP协议是面向无连接的网络协议,服务器无法得知用户在请求页面之前的行为,这种方式虽然阻碍了交互Web的效率,但是却简单易实现[8]。爬虫就是将数据从后台提取出来,并不是像web那样将数据渲染到友好的用户界面上,而把这些数据整合提取并且进行存储,按照一定的规则进行整合存储。爬虫是web的延续,数据分析,机器学习,人工智能都需要海量的数据去进行训练,并且去进行对数据的处理。海量的数据就要从第三方的网站爬取。数据分析,机器学习,人工智能主要是处理数据。爬虫的责任就是获取到所需要的数据。5.2创建项目工程确定要爬取的网页,在这里我们爬取网页是智联招聘网站。需要爬取的信息输入scrapystartproject后面跟上项目的名字就可以创建一个项目。创建项目打开pycharm,找到刚刚创建的项目,打开项目。打开工程目录项目里面有一个子目录,子目录的名字跟工程名一样,有一个scrapy.cfg文件,这个文件很少会用到,但是不能删除,删除以后会导致所有scrapy命令都用不了了。这个文件主要是对接scrapy命令和代码,在这里这个scrapy.cfg文件不需要理会就好。子目录中有很多文件,其中的setting文件是爬虫的相关的配置文件,在里面配置工程的设置。5.3数据的请求增量式爬虫可以以某个页面为基准,不断的增加待爬取的URL,可以让引擎不断的增加URL请求的调度。普通爬虫爬取完一个页面以后,解析完数据以后就结束。根据需求,在项目中缺少一个增量式爬虫来爬取智联网站上的所有的职业,在终端输入scrapygenspider-tcrawljobs命令来创建一个爬虫,这个爬虫用来爬取所有的职业。新建增量式爬虫导入LinkExtractor对象,用于从页面上提取URL。导入Crawlspider,Rule是一个规则对象,根据LinkExtractor里面匹配的那些URL进行提取并且发起请求。在scrapy框架里面,里面有很多爬虫模板,最常用的是basic爬虫和CrawlSpider,spider设计理念start_urls列表中提取起始URL。CrawlSpider理念是首先从start_urls里面提取起始的url,并且发起请求,从这些响应的页面中根据一定的规则去跟踪一系列的链接,从中提取出这些链接,放入到调度器的调度队列中,调度器调度下载,然后再从新的页面中根据规则重新提取新的url,然后去重,把新出现的url放入到调度队列,依次类推,直至所有的页面的url都匹配完成。在网页中复制URL,更改起始URL。我们自己写的爬虫,robots协议并不需要遵守,在setting.py文件中将ROBOTSTXT_OBEY改为FalseROBOTSTXT_OBEY=False加入USER_AGENT,去网页中复制一个请求头。USER_AGENT='Mozilla/5.0(WindowsNT10.0;WOW64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/71.0.3578.98Safari/537.36'在setting.py文件中设置下载时延为1秒,避免服务器将我们的ip地址禁止。DOWNLOAD_DELAY=1管道暂时不需要打开。在item文件中定义要爬取的内容,在这里需要爬取的内容有岗位,公司、工资、要求、规模、公司简介、职位介绍、公司地址。classBossproItem(scrapy.Item):job=scrapy.Field()conpany=scrapy.Field()salary=scrapy.Field()require=scrapy.Field()size=scrapy.Field()company_info=scrapy.Field()job_info=scrapy.Field()address=scrapy.Field()在jobs.py文件中,将BossproItem导入,在要爬取的网页上找匹配规则,使用正则表达式来匹配是最快的。匹配page等于某某某是最快的,前面的不轻易匹配,前面只是匹配某个城市某个职位。网页源码根据其的规则,选择正则表达式来进行匹配。rules=(Rule(LinkExtractor(allow=r'page=\d'),callback='parse_item',follow=True),)rules规则:包含若干个Rule对象,每一个Rule都会对我们爬取的网站的URL规则做一个特定的匹配规则,匹配的依据来自它里面的参数LinkExtractor,对匹配的么一个URL都对应一个回调函数,这个回调函数这里写成了一个字符串。5.4数据的解析在解析之前先安装xpath的插件,将浏览器更改为开发者模式,启动XPathHelper插件。安装xpath插件根据其前端页面的代码的节点的关系,使用xpath提取出起始url。对该URL发起一个get请求,一级页面不进行解析,所有的数据都放在二级页面进行解析。请求二级页面,需要发起一个二级页面的请求。手动调动下载器,进行二级页面的请求。需要在外界定义一个函数,用于解析。下载器下载完页面以后,就会调用该函数来进行解析。如何将一级页面和二级页面的内容存储到同一个item中。回调函数接收什么内容自己做不了主,request让接收什么只能接收什么。meta是响应对象的一个属性,也是其一个参数,当请求成功完成以后,就会构建一个响应对象,响应对象里面包含了所有的响应头和响应体,其中meta就是响应头的一部分内容,即是响应对象的一部分,此时对meta进行自定义的内容加入,meta就可以把这些内容带到响应中。此时的response除了携带上个页面的响应对象以外还携带上个页面的item。在这里创建一个下载器的get对象,并没有进行调用,需要在引擎迭代的时候才能调用,需要把这些请求对象加入到一个容器中并且返回。defparse_item(self,response):job_list=response.xpath("//div[@class='job-list']//li")forjobinjob_list:next_url=""+job.xpath(".//h3//a/@href").extract_first()yieldscrapy.Request(url=next_url,callback=self.parse_info)defparse_info(self,response):item=BossproItem()item["job"]=response.xpath("//h1/text()").extract_first()item["salary"]=response.xpath("//span[@class='badge']/text()").extract_first()yielditem在settings.py文件中打开下载时延,不开下载时延会出现会遇到ip禁止和输入验证码的反爬措施。为了避免这些验证码和ip禁止的问题,可以设置下载时延。DOWNLOAD_DELAY=1不开下载时延的验证码问题5.5分布式执行流程分布式数据库中有4个key,分别是start_urls,requests,item,dupefilter。分布式数据库中的keystart_urls:起始url在开启分布式爬虫之前首先要将起始url压入到这个key中,分布式系统里面所有的知己同时去竞争这些起始url,然后解析出一堆新的url,会放入到request这个key中。requests这个key用于存放爬取过程中新产生的那些url,当分布式系统中的某一个爬虫产生新的url以后首先会查找这些url有没有在dupefilter中存在,如果有则忽略,否则就会被压入到requests这个key中item用于存储所有的爬虫解析出来的数据,每一台主机在完成请求数据以后,解析内容,并且通过redis的管道组件将内容放入到这个key中dupefilter这个key用于存放成功访问过的那些url,用于去重,去重的原理,所有的爬虫url要么来源于start_urls要么来源于requests,如果某个爬虫从来源处获取到了某个url以后,如果请求成功则将这个url从来源删除并且压入到这个key中,如果访问不成功则将这个url重新压入到requests里面,然后供这个系统中的爬虫共享。master端部署redis数据库服务器,salaver端部署分布式爬虫框架,所有的分机把爬虫执行起来由于start_urls当前还没有,所有的slaver端的爬虫都处于等待状态,通过服务端的脚本把起始的url以“xxx:start_urls”这个键压入到服务器中。所有的slaver去竞争master的start_urls,一旦某个主机竞争到url则立即进入请求爬取,没有竞争到的那些爬虫开始监视“xxx:requests”。所有的获取到的起始url的那些分机解析出一堆新的url压入到requests到item中,访问过那些url进入到depefilter中。所有的爬虫竞争requests里面的url,爬取产生新的url周而复始直至所有的url全部被爬取完为止。要进行分布式部署,在settings文件中打开管道,打开远程管道,给出其的优先级。ITEM_PIPELINES={"scrapy_redis.pipelines.RedisPipeline":400,}加入远程redis链接的主机名,端口号。加入调度器,在调度过程中要允许暂停。REDIS_HOST=""REDIS_PORT=6379SCHEDULER="scrapy_redis.scheduler.Scheduler"SCHEDULER_PERSIST=TrueDUPEFILTER_CLASS='scrapy_redis.dupefilter.RFPDupeFilter'在jobs文件中导入RedisCrawlSpider,将类的继承改为RedisCrawlSpider,不要start_urls,改为redis_key="jobs:start_urls"这样就可以就可以进行分布式爬虫爬取。5.6服务端脚本首先查看城市的网页是动态加载还是静态加载,在静态网页中没有找到城市,说明城市是由动态加载的。服务端的脚本需要用selenium来写,服务端的脚本只需要写一个就好。通过JS来动态网页,通过HTTP协议请求得到的只是一些动态页面的源码,这些源码对于我们来说没有任何的价值。想从源码上获取到我们需要的数据,想到的是我们可以执行那些源码,这些源码都会装换成页面中的内容。python不能执行JavaScript源码,JavaScript语言是前端的专用语言,爬虫中python框架执行不了JavaScript源码,也没有第三方库可以执行JavaScript的源码。selenium是一种用于web程序测试的工具,selenium测试的代码可以直接运行在浏览器中,如同真实的用户操作一样。selenium可以操作浏览器,通过驱动这个桥梁去操作浏览器。配置seleniumpipinstallselenium在下载驱动之前,查看浏览器版本和浏览器之间的映射表,下载与浏览器版本相对应的浏览器驱动。导入selenium工具,导入time库fromseleniumimportwebdriverfromtimeimportsleep定义一个函数,用于提取所有的URL,创建浏览器的驱动对象。用chrome浏览器,发起一个get请求。defget_urls():driver=webdriver.Chrome()driver.get(“https://www//”)sleep(3)html_tree=etree.HTML(driver.page_source)用xpath来解析。city_list=html_tree.xpath(“//li[starts-with(@ka,’hot-city’)@data-val”)job_list=html_tree.xpath(“//div[@class=’menu-sub’]//li//a/@href”)对URL进行拼接。forcityincity_list:forjobinjob_list:job_url=”/c”+city+”-”+job.split(“-”)[-1]要定义一个函数将url写入到redis数据库中,这个redis数据库要和分布式爬虫对接上。要创建一个redis链接,要有数据库地址端口号和数据库,导入redis库。要对url列表进行遍历,每遍历一次就要将url进行lpush一次。defwrite_to_redis(url_list):rds=redis.StrictRedis(host=””,port=6379,db=0)forurlinurl_list:rds.lpush(“jobs:start_urls”,url)if__name__==’__main__’:write_to_redis(get_urls())第六章代理服务器6.1代理的原理在爬虫的过程中,最初爬虫正常运行,正常抓取数据,一切看起来是那么的美好,可是过了一段时间以后,就会出现“你的访问频率太高”的提示。出现这种现象的原因是网站采取了一些反爬虫的措施。服务器会检测某个IP在单位时间内的请求次数,如果超过了这个值,就会直接拒绝访问。既然服务器检测的是某个IP在单位时间内的请求次数,我们可以借助某种方式来伪装我们的IP,让服务器识别不出来是本机进行发起的请求,就可以解决IP禁止了。图6-1IP被禁止代理也就是指代理服务器,具体的功能就是让网络用户去取得网络信息,代理服务器就是网络信息的中转站,我们在正常地请求一个网站的时候,主机是直接发送请求给了Web服务器,Web服务器直接把响应返回给我们。如果设置了代理服务器,实际上就是在本机和服务器之间搭建了一个桥,使得本机不会直接把请求发送给Web服务器,先向代理服务器发起请求,然后代理服务器将我们的请求发送给Web服务器,再由代理服务器去接收Web返回来的响应,由代理服务器将Web返回的响应直接转发给我们本机。这样我们的主机就可以正常地访问网页,在这个过程中,Web服务器识别的IP地址并不是我们的本机的IP地址,而是代理服务器。这样就能实现IP伪装。本机本机 请求响应数据代理服务器代理服务器请求响应数据web服务器web服务器图代理原理使用代理可以提高访问速度,通常代理服务器都设置有一个硬盘的缓冲区,当外界信息通过的时候,同时将其保存到缓冲区中,当其他用户再访问相同的信息的时候,则由缓冲区取出信息,传给用户。隐藏真实的IP,,避免自身的IP被封锁,达到爬取的效果。6.2设置代理池需要导入系统的代理服务器中间件的基类。构建代理池的设置找到代理的中间件,把系统的中间件禁止掉,开启自定义的中间件,在自定义的中间件中构建IP代理池。配置代理服务器,打开管道,把scrapy.downloadmiddlewares.httpproxy.HttpProxyMiddleware中间件禁止掉,设置为NoneDOWNLOADER_MIDDLEWARES={"scrapy.downloadmiddlewares.httpproxy.HttpProxyMiddleware":None,}6.3抓取代理西刺代理是国内的免费代理网站。图6-2西刺代理在spiders文件夹中新建一个pythonFile文件。在python文件中导入请求模块requests和解析模块lxml。定义一个方法,去抓取西刺代理,需要请求头,在网页拷贝user_agent,复制西刺代理的URL。使用requests模块的get请求,加入超时(timeout),两秒钟没有反应就认为超时。抓取10页代理,使用for循环。每抓取一个代理,就睡眠一段时间,返回一个HTML页main。defcrawlProxy():headers={"user-agent":'Mozilla/5.0(WindowsNT10.0;WOW64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/71.0.3578.98Safari/537.36'}url="/nn/"foriinrange(1,11):res=requests.get(url=url+str(i),headers=headers,timeout=2)sleep(8)yieldres.text定义一个函数,来解析HTML页面,需要找到代理的IP,端口号,defparse_page(pages):forpageinpages:page_tree=etree.HTML(page)ip_list=page_tree.xpath("//table[@id='ip_list']//tr")[1:]foripinip_list:proxy={}proxy["cat"]=ip.xpath(".//td[6]/text()")[0]proxy["ip"]=ip.xpath(".//td[2]/text()")[0]proxy["port"]=ip.xpath(".//td[3]/text()")[0]yieldproxy图6-3解析出来的代理过滤有效的代理,把无效的代理删除掉。定义一个方法,用于过滤验证,把爬取到的代理列表传入,循环取出列表中代理,拼接处理代理。使用requests模块的get方法来检验代理。设置超时,超过了设置的时间就认为异常。如果请求成功就是代理可用。将可以请求的代理,yield出去。defverify_proxy(proxies):forproxyinproxies:proxy_dic={proxy["cat"]:proxy["ip"]+":"+proxy["port"]}try:res=requests.get(url="/s?wd=ip",headers={"user-agent":'Mozilla/5.0(WindowsNT10.0;WOW64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/71.0.3578.98Safari/537.36'},proxies=proxy_dic)print("可用代理:",proxy_dic)withopen("ip.html",'wb')asfp:fp.write(res.content)yieldproxy_dicexceptexceptions.HTTPErrorase:print("代理-%s--不可用!"%proxy_dic)print(e)图6-4有效的代理将可用代理写入redis数据库。定义一个方法,用于将可用的代理写入数据库中,使用循环遍历代理生成器,写入代理。defwrite_to_redis(proxies):rds=redis.StrictRedis(host="",port=6379,db=8)forproxyinproxies:rds.lpush("proxy",proxy)图6-5代理写入数据库6.4搭建代理池重写__init__方法。获取数据库中的代理,需要导入redis模块。先确定代理列表的长度,根据它的长度将代理全部取出。classProxyDownloaderMiddleware(object):def__init__(self):self.ippool=self.get_ippool()defget_ippool(self):rds=redis.StrictRedis(host="",port=6379,db=8)len=rds.llen("proxy")proxies=rds.lrange("proxy",0,len)returnproxies定义一个方法,用于更新代理池。更新代理池的方法有很多,可以购买代理、抓取免

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论