Python构建网页爬虫原理分析
既然本篇文章说到的是Python构建网页爬虫原理分析,那么小编先给大家看一下Python中关于爬虫的精选文章:
网络爬虫是当今最常用的系统之一。最流行的例子是 Google 使用爬虫从所有网站收集信息。除了搜索引擎之外,新闻网站还需要爬虫来聚合数据源。看来,只要你想聚合大量的信息,你可以考虑使用爬虫。
建立一个网络爬虫有很多因素,特别是当你想扩展系统时。这就是为什么这已经成为最流行的系统设计面试问题之一。在这篇文章中,我们将讨论从基本爬虫到大型爬虫的主题,并讨论在面试中可能会遇到的各种问题。
1 - 基本解决方案
如何建立一个基本的网络爬虫?
在系统设计面试之前,我们已经在《系统设计面试之前需要知道的八件事》中谈到,就是从简单的东西开始。让我们专注于构建在单线程上运行的基本网页爬虫。有了这个简单的解决方案,我们可以继续优化。
要抓取单个网页,我们只需要向相应的 URL 发出 HTTP GET 请求,并解析响应数据,这是抓取工具的核心。考虑到这一点,一个基本的网络爬虫可以这样工作:
以包含我们要抓取的所有网站的网址池开始。
对于每个 URL,发出 HTTP GET 请求来获取网页内容。
解析内容(通常为 HTML)并提取我们想要抓取的潜在网址。
添加新的网址到池中,并不断抓取。
这取决于具体问题,有时我们可能会有一个独立的系统来生成抓取网址。例如,一个程序可以不断监听 RSS 订阅,并且对于每个新文章,都可以将该 URL 添加到爬取池中。
2 - 规模问题
众所周知,任何系统在扩展后都会面临一系列问题。在网络爬虫中,将系统扩展到多台机器时,有很多东西可能出错。
在跳转到下一节之前,请花几分钟的时间思考一下分布式网络爬虫的瓶颈,以及如何解决这个问题。在这篇文章的其余部分,我们将讨论解决方案的几个主要问题。
3 - 抓取频率
你多久爬一次网站?
这听起来可能不是什么大事,除非系统达到一定的规模,而且你需要非常新鲜的内容。例如,如果你想要获取上一小时的最新消息,则抓取工具可能需要每隔一小时不断抓取新闻网站。但是这有什么问题呢?
对于一些小型网站,他们的服务器很可能无法处理这种频繁的请求。一种方法是遵循每个站点的robot.txt。对于不知道robot.txt是什么的人,这基本是网站与网络爬虫交流的标准。它可以指定不应该抓取什么文件,大多数网络爬虫都遵循配置。另外,你可以为不同的网站设置不同的抓取频率。通常,每天只有几个网站需要被多次抓取。
4 - 去重
在一台机器上,你可以将 URL 池保留在内存中,并删除重复的条目。但是,分布式系统中的事情变得更加复杂。基本上,多个爬虫可以从不同的网页中提取相同的 URL,他们都希望将这个 URL 添加到 URL 池中。当然,多次抓取同一页面是没有意义的。那么我们如何去重复这些网址?
一种常用的方法是使用 Bloom Filter。简而言之,布隆过滤器是一个节省空间的系统,它允许你测试一个元素是否在一个集合中。但是,它可能有误报。换句话说,如果布隆过滤器可以告诉你一个 URL 绝对不在池中,或者可能在池中。
为了简要地解释布隆过滤器是如何工作的,空布隆过滤器是m位(全0)的位数组。还有k个散列函数,将每个元素映射到m位中的一个。所以当我们在布隆过滤器中添加一个新的元素(URL)时,我们将从哈希函数中得到k位,并将它们全部设置为1.因此,当我们检查一个元素的存在时,我们首先得到k位,如果它们中的任何一个不是1,我们立即知道该元素不存在。但是,如果所有的k位都是1,这可能来自其他几个元素的组合。
布隆过滤器是一个非常常用的技术,它是一个完美的解决方案,用于在网络爬虫中去重网址。
5 - 解析
从网站获取响应数据后,下一步是解析数据(通常是 HTML)来提取我们所关心的信息。这听起来像一个简单的事情,但是,可能很难使其健壮。
我们面临的挑战是,你总是会在 HTML 代码中发现奇怪的标记,URL 等,很难涵盖所有的边界情况。例如,当 HTML 包含非 Unicode 字符时,你可能需要处理编解码问题。另外,当网页包含图片,视频甚至PDF 时,也会造成奇怪的行为。
另外,一些网页都像使用 AngularJS 一样通过 Javascript 呈现,你的抓取工具可能无法得到任何内容。
我会说没有银弹,不能为所有的网页做一个完美的,健壮的爬虫。你需要大量的健壮性测试,以确保它能够按预期工作。
总结
还有很多我还没有涉及到的有趣的话题,但是我想提一下其中的一些,这样你就可以思考了。有一件事是检测循环。许多网站包含链接,如A->B->C->A,你的爬虫可能会永远运行。想想如何解决这个问题?
另一个问题是 DNS 查找。当系统扩展到一定的水平时,DNS 查找可能是一个瓶颈,你可能要建立自己的 DNS 服务器。
与许多其他系统类似,扩展的网络爬虫可能比构建单个机器版本困难得多,并且在系统设计面试中可以讨论许多事情。尝试从一些朴素的解决方案开始,并继续优化它,这可以使事情变得比看起来更容易。
以上就是我们总结的关于网页爬虫的相关文章内容,大家如果还有其他想知道的可以在下方的留言区域讨论,感谢大家对脚本之家的支持。
- mac上开启ftp
- Web前端开发的四个阶段
- 使用Visual Studio 2015 开发ASP.NET MVC 5 项目部署到Mono/Jexus
- 关于把本地应用封装成windows app发布审核通不过的问题
- java并发编程学习:用 Semaphore (信号量)控制并发资源
- java并发编程学习: ThreadLocal使用及原理
- 使用Autofac IOC组织多项目应用程序
- 国内首个“人工智能与变革管理研究院”成立
- 解决WordPress缩略图插件timthumb不支持站外图片的问题
- 让 http 2来得更猛烈些吧
- SQL Server 2008基于策略的管理
- centos系统安装Python
- rpc框架之 thrift连接池实现
- .NET Core全新路线图
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法