java抓取网页数据(如何自动高效地获取互联网中我们感兴趣的信息并实现)
优采云 发布时间: 2022-01-30 12:19java抓取网页数据(如何自动高效地获取互联网中我们感兴趣的信息并实现)
1. 什么是网络爬虫?
在大数据时代,信息采集是一项重要的任务,互联网中的数据是海量的。如果信息采集单纯依靠人力,不仅效率低下、繁琐,而且采集成本也会有所提高。如何在互联网上自动、高效地获取我们感兴趣的信息并为我们所用是一个重要的问题,而爬虫技术就是为了解决这些问题而诞生的。
网络爬虫,也称为网络机器人,可以代替人自动采集并组织互联网上的数据和信息。它是一个程序或脚本,根据一定的规则自动从万维网上抓取信息,并且可以自动采集它可以访问的页面的所有内容来获取相关数据。
从功能上来说,爬虫一般分为数据采集、处理、存储三部分。爬虫从一个或多个初始网页的URL开始,获取初始网页上的URL。在抓取网页的过程中,它不断地从当前页面中提取新的 URL 并放入队列中,直到满足系统的某些停止条件。
2. 网络爬虫的作用
1.可以实现搜索引擎
在我们学会了爬虫的编写之后,就可以利用爬虫自动采集互联网上的信息,采集返回相应的存储或处理。当我们需要检索一些信息的时候,我们只需要采集@采集检索返回的信息,也就是实现一个私有的搜索引擎。
2.大数据时代,我们可以获得更多的数据源
在进行大数据分析或数据挖掘时,需要有数据源进行分析。我们可以从一些提供统计数据的网站中获取数据,或者从某些文献或内部资料中获取数据,但是这些获取数据的方式有时很难满足我们对数据的需求,需要手动从网上获取数据。查找这些数据需要花费太多精力。此时,我们可以利用爬虫技术从互联网上自动获取我们感兴趣的数据内容,并将这些数据内容爬回作为我们的数据源,进而进行更深层次的数据分析,获取更有价值的信息。
3. 用于更好的搜索引擎优化 (SEO)
对于很多SEO从业者来说,要想更好的完成自己的工作,就必须非常清楚搜索引擎的工作原理,也需要掌握搜索引擎爬虫的工作原理。而学习爬虫,可以更深入的了解搜索引擎爬虫的工作原理,让你在做搜索引擎优化的时候,知己知彼,百战百胜。
3.网络爬虫是如何工作的?
爬虫底部有两个核心:
(1).HttpClient:网络爬虫使用程序来帮助我们访问互联网上的资源。我们一直使用HTTP协议来访问互联网上的网页。网络爬虫需要编写程序来使用相同的HTTP访问网页协议,这里我们使用Java的HTTP协议客户端HttpClient技术来抓取网页数据。(在Java程序中,远程访问是通过HttpClient技术来抓取网页数据。)
注意:如果每次请求都需要创建HttpClient,就会出现频繁创建和销毁的问题。你可以使用 HttpClient 连接池来解决这个问题。
(2).jsoup:我们抓取页面后,还需要解析页面。可以使用字符串处理工具来解析页面,也可以使用正则表达式,但是这些方法会带来很多开发cost ,所以我们需要使用专门解析html页面的技术。(将获取的页面数据转换成Dom对象进行解析)
Jsoup简介:Jsoup是一个Java HTML和XML解析器,可以直接将一个URL地址、HTML文本、文件解析成DOM对象。使用 jQuery 的 action 方法获取 sum 操作数
设置抓取目标(*敏*感*词*页面)并获取网页。无法访问服务器时,设置重试次数。设置用户代理在需要时(否则页面无法访问)通过正则表达式对获取的页面进行必要的解码操作获取页面中的链接对链接进行进一步处理(获取页面并重复上述操作)持久有用信息(用于后续处理)
5. WebMagic 简介
WebMagic 是一个爬虫框架。底层使用了上面介绍的HttpClient和Jsoup,可以让我们更方便的开发爬虫。WebMagic 的设计目标是尽可能模块化,并体现爬虫的功能特点。这部分提供了一个非常简单灵活的API来编写爬虫,而无需基本改变开发模式。
WebMagic 项目代码分为核心和扩展两部分。核心部分(webmagic-core)是一个精简、模块化的爬虫实现,而扩展部分(webmagic-extension)包括一些方便实用的功能,比如用注解的方式编写爬虫,以及一些常用的内置功能。易于爬虫开发的组件。
1).架构介绍
WebMagic 的结构分为四个组件:Downloader、PageProcessor、Scheduler 和 Pipeline,它们由 Spider 组织。这四个组件分别对应了爬虫生命周期中的下载、处理、管理和持久化的功能。
Spider 组织这些组件,以便它们可以相互交互并处理执行。Spider可以看作是一个大容器,也是WebMagic逻辑的核心。
WebMagic的整体架构图如下:
2).WebMagic 的四个组成部分
①.下载器
下载器负责从 Internet 下载页面以进行后续处理。WebMagic 默认使用 Apache HttpClient 作为下载工具。
②.PageProcessor
PageProcessor 负责解析页面、提取有用信息和发现新链接。WebMagic 使用 Jsoup 作为 HTML 解析工具,并在其基础上开发了 Xsoup,一个解析 XPath 的工具。
这四个组件中,PageProcessor对于每个站点的每个页面都是不同的,是需要用户自定义的部分。
③.调度器
Scheduler 负责管理要爬取的 URL,以及一些去重工作。WebMagic 默认提供 JDK 的内存队列来管理 URL,并使用集合进行去重。还支持使用 Redis 进行分布式管理。
④.流水线
Pipeline负责提取结果的处理,包括计算、持久化到文件、数据库等。WebMagic默认提供两种结果处理方案:“输出到控制台”和“保存到文件”。
Pipeline 定义了保存结果的方式。如果要保存到指定的数据库,需要编写相应的Pipeline。通常,对于一类需求,只需要编写一个 Pipeline。
3).Object 用于数据流
①。要求
Request是对URL地址的一层封装,一个Request对应一个URL地址。它是PageProcessor 与Downloader 交互的载体,也是PageProcessor 控制Downloader 的唯一途径。除了 URL 本身,它还收录一个 Key-Value 结构的额外字段。你可以额外保存一些特殊的属性,并在其他地方读取它们来完成不同的功能。例如,添加上一页的一些信息等。
②。页
Page 表示从 Downloader 下载的页面 - 它可能是 HTML、JSON 或其他文本内容。页面是WebMagic抽取过程的核心对象,它提供了一些抽取、结果保存等方法。
③。结果项
ResultItems相当于一个Map,它保存了PageProcessor处理的结果,供Pipeline使用。它的API和Map非常相似,值得注意的是它有一个字段skip,如果设置为true,它不应该被Pipeline处理。
6.WebMagic 的工作原理
1)。PageProcessor 组件的功能
①。提取元素可选
可选相关提取元素链接 API 是 WebMagic 的核心功能。使用Selectable接口,可以直接完成页面元素的链式提取,无需关心提取的细节。page.getHtml() 返回一个实现 Selectable 接口的 Html 对象。这部分提取API返回一个Selectable接口,表示支持链式调用。该接口收录的方法分为两类:提取部分和获取结果部分。
方法
操作说明
例子
xpath(字符串 xpath)
使用 XPath 选择
html.xpath("//div[@class='title']")
$(字符串选择器)
使用 Css 选择器进行选择
html.$("div.title")
$(字符串选择器,字符串属性)
使用 Css 选择器进行选择
html.$("div.title","text")
css(字符串选择器)
功能同$(),使用Css选择器选择
html.css("div.title")
链接()
选择所有链接
html.links()
正则表达式(字符串正则表达式)
使用正则表达式提取
html.regex("\(.\*?)\")
PageProcessor 中使用了三种主要的提取技术:XPath、CSS 选择器和正则表达式。对于 JSON 格式的内容,可以使用 JsonPath 进行解析。
1. XPath
以上是获取属性class=mt的div标签,以及里面的h1标签的内容
2.CSS 选择器
CSS 选择器是一种类似于 XPath 的语言。
div.mt>h1 表示类为mt的div标签下的直接子元素h1标签
但是使用:nth-child(n) 选择第一个元素,如下选择第一个元素
注意:你需要使用 > 是直接子元素来选择前几个元素
3.正则表达式
正则表达式是一种通用的文本提取语言。这里一般用来获取url地址。
②。得到结果
当链式调用结束时,我们一般希望得到一个字符串类型的结果。这时候就需要使用API来获取结果了。
我们知道,一条抽取规则,无论是 XPath、CSS 选择器还是正则表达式,总是可以抽取多个元素。WebMagic 将这些统一起来,可以通过不同的 API 获取一个或多个元素。
方法
操作说明
例子
得到()
返回字符串类型的结果
字符串链接= html.links().get()
toString()
和get()一样,返回一个String类型的结果
字符串链接= html.links().toString()
全部()
返回所有提取结果
Listlinks= html.links().all()
多条数据时,使用get()和toString()获取第一个url地址。
检测结果:
selectable.toString() 在输出和结合一些框架的时候比较方便。因为一般情况下,我们只使用这种方法来获取一个元素!
③。获取链接
一个网站的页面很多,不可能一开始就全部列出来,所以如何找到后续链接是爬虫必不可少的环节。
下面的例子就是获取这个页面
与 \\w+?.* 正则表达式匹配的所有 url 地址
并将这些链接添加到要爬取的队列中。
2)。调度器组件的使用
解析页面时,很可能会解析相同的url地址(比如商品标题和商品图片超链接,url相同)。如果不处理,同一个url会被多次解析处理,浪费资源。所以我们需要有一个url去重功能。
调度器可以帮助我们解决以上问题。Scheduler 是 WebMagic 中用于 URL 管理的组件。一般来说,Scheduler包括两个功能:
❶ 管理要抓取的 URL 队列。
❷ 对爬取的 URL 进行去重。
WebMagic 内置了几个常用的调度器。如果只是在本地执行小规模的爬虫,基本上不需要自定义Scheduler,但是了解几个已经提供的Scheduler还是有意义的。
种类
操作说明
评论
DuplicateRemovedScheduler
提供一些模板方法的抽象基类
继承它来实现自己的功能
队列调度器
使用内存队列保存要抓取的 URL
优先调度器
使用优先级的内存队列来保存要爬取的 URL
它比QueueScheduler消耗更多的内存,但是设置了request.priority时,只能使用PriorityScheduler来使优先级生效
文件缓存队列调度器
使用文件保存爬取的URL,关闭程序下次启动就可以从之前爬取的URL继续爬取
需要指定路径,会创建两个文件.urls.txt和.cursor.txt
Redis调度器
使用Redis保存抓取队列,可用于多台机器同时协同抓取
需要安装并启动redis
去除重复链接的部分被抽象成一个接口:DuplicateRemover,这样可以为同一个Scheduler选择不同的去重方法,以适应不同的需求。目前提供了两种去重方法。
种类
操作说明
HashSetDuplicateRemover
使用HashSet进行去重,占用大量内存
BloomFilterDuplicateRemover
使用BloomFilter进行去重,占用内存少,但可能会漏页
RedisScheduler 使用 Redis set 进行去重,其他 Scheduler 默认使用 HashSetDuplicateRemover 进行去重。
如果要使用BloomFilter,则必须添加以下依赖项:
修改代码添加布隆过滤器
三种去重方法的比较
❶ HashSetDuplicateRemover
利用java中HashSet不能重复的特性来去除重复。优点是易于理解。使用方便。
缺点:内存占用大,性能低。
❷.RedisScheduler 的集合去重。
优点是速度快(Redis本身很快),去重不会占用爬虫服务器的资源,可以处理数据量较大的数据爬取。
缺点:需要准备Redis服务器,增加了开发和使用成本。
❸.BloomFilterDuplicateRemover
重复数据删除也可以使用布隆过滤器来实现。优点是占用的内存比使用HashSet小很多,也适合大量数据的去重操作。
缺点:有误判的可能。没有重复可能会被判定为重复,但重复的数据肯定会被判定为重复。
*删除页面内容
以上,我们研究了对下载的url地址进行去重,避免多次下载同一个url的解决方案。其实不仅url需要去重,我们还需要对下载的网页内容去重。我们可以在网上找到很多文章类似的内容。但实际上我们只需要其中一个,相同的内容不需要多次下载,所以需要处理如何去重复
重复数据删除程序介绍
❶。指纹代码对比
最常见的重复数据删除方案是生成文档的指纹门。例如,如果一个文章被MD5加密生成一个字符串,我们可以认为这是文章的指纹码,然后与其他文章指纹码进行比较。如果它们一致,则表示 文章 重复。但是这种方法是完全一致的,并且是重复的。如果 文章 只是多了几个标点符号,仍然认为是重复的。这种方法是不合理的。
❷.BloomFilter
这种方法是我们用来对 url 进行重复数据删除的方法。如果我们在这里使用它,我们也会为 文章 计算一个数字,然后进行比较。缺点与方法 1 相同,只是略有不同。,也会认为不重复,这种方法不合理。
❸.KMP算法
KMP 算法是一种改进的字符串匹配算法。KMP算法的关键是利用匹配失败后的信息,尽可能减少模式串与主串的匹配次数,以达到快速匹配的目的。可以找出这两个 文章 中哪些是相同的,哪些是不同的。这种方法可以解决前两种方法中的“只要一个不同,就不重复”的问题。但其时间和空间复杂度太高,不适合大量数据的重复比较。
❹。Simhash 签名
Google 的 simhash 算法生成的签名可以满足上述要求。这个算法并不深奥并且相对容易理解。该算法也是目前谷歌搜索引擎使用的网页去重算法。
(1).SimHash流程介绍
Simhash 是 Charikar 在 2002 年提出的,为了便于理解,尽量不要使用数学公式。它分为以下几个步骤:
1、分词,需要判断的文本的分词,形成这个文章的特征词。
2、hash,通过哈希算法将每个单词变成一个哈希值。例如,“美国”通过哈希算法计算为100101,“51”通过哈希算法计算为101011。这样我们的字符串就变成了一串数字。
3、称重,结果通过2步散列生成。需要根据单词的权重形成加权数字串。“美国”的哈希值为“100101”,加权计算为“4 -4 -4 4 -4 4”
“区域 51”计算为“5 -5 5 -5 5 5”。
4、合并,把上面的话计算出来的序列值累加起来,变成只有一个序列串。
“美国”为“4 -4 -4 4 -4 4”,“51 区”为“5 -5 5 -5 5 5”
累加每一位,“4+5 -4+-5 -4+5 4+-5 -4+5 4+5”à“9 -9 1 -1 1 9”
5、降维,将计算出来的“9 -9 1 -1 1 9”变成0 1字符串,形成最终的simhash签名。
(2).签名距离计算
我们将库中的文本转成simhash签名,转成long类型存储,大大减少了空间。既然我们已经解决了空间问题,那么如何计算两个 simhash 的相似度呢?
我们可以通过汉明距离来计算两个simhash是否相似。两个simhash对应的二进制(01字符串)不同值的个数称为两个simhash的汉明距离。
(3).test simhash
本项目不能直接使用,因为jar包的问题,需要导入项目simhash并安装。
导入对应的依赖:
测试用例:
检测结果:
3)。管道组件的使用
Pipeline 组件的作用是保存结果。我们现在对“控制台输出”所做的事情也是通过一个名为 ConsolePipeline 的内置管道完成的。
那么,我现在想将结果保存到文件中,该怎么做呢?只需将 Pipeline 的实现替换为“FilePipeline”即可。
7.网络爬虫的配置、启动和终止
1).蜘蛛
Spider 是网络爬虫启动的入口点。在启动爬虫之前,我们需要使用 PageProcessor 创建一个 Spider 对象,然后使用 run() 来启动它。
Spider的其他组件(Downloader、Scheduler)可以通过set方法进行设置,
管道组件是通过 add 方法设置的。
方法
操作说明
例子
创建(页面处理器)
创建蜘蛛
Spider.create(new GithubRepoProcessor())
addUrl(字符串...)
添加初始 URL
蜘蛛.addUrl("")
线程(n)
打开 n 个线程
蜘蛛.thread(5)
跑()
启动,会阻塞当前线程执行
蜘蛛.run()
开始()/运行异步()
异步启动,当前线程继续执行
蜘蛛.start()
停止()
停止爬虫
蜘蛛.stop()
添加管道(管道)
添加一个Pipeline,一个Spider可以有多个Pipeline
蜘蛛 .addPipeline(new ConsolePipeline())
setScheduler(调度器)
设置Scheduler,一个Spider只能有一个Scheduler
spider.setScheduler(new RedisScheduler())
setDownloader(下载器)
设置Downloader,一个Spider只能有一个Downloader
蜘蛛 .setDownloader(
新的 SeleniumDownloader())
获取(字符串)
同步调用,直接获取结果
ResultItems 结果 = 蜘蛛