很多人在搜索机票,发现机票价格在白天波动。因此试图找出最佳的购票时间,但网上没有任何帮助。程序员就会构建了一个小程序来自动从Web收集数据所谓的刮板程序。它在预定日期提取了特定航班目的地的信息,并在价格降低时通知到使用的人。Web抓取是一种用于通过自动化过程从网站提取数据的技术。从这种Web抓取的经验中学到了很多东西,下面是详细介绍。
有兴趣了解与网页抓取相关的常见设计模式,陷阱和规则的人员使用。该ariticle存在一些使用案例和典型的集合的问题,比如如何不被检测到,DOS和注意事项,以及如何加快(并行)的刮刀。
一切都会伴随有python代码段,因此您可以立即开始。本文档还将介绍一些有用的python软件包。
用例
您想抓取数据的原因和用例有很多。让我列出其中一些:
· 刮擦电子零售商的页面以发现您要购买的某些衣服是否打折;
· 通过抓取页面来比较几个服装品牌的价格;
· 机票价格白天可能会有所不同。价格降低后,一个人可能会爬行旅行网站并惊慌;
· 分析行动网站以回答以下问题:起始出价应低还是高以吸引更多竞标者,或者更长的拍卖与更高的最终出价相关。
讲解
本教程的结构:
1. 可用包装;
2. 基本代码;
3. 陷阱;
4. 该做什么和不该做什么;
5. 加速—并行化。
在我们开始之前:对服务器要好一些;您不想使网站崩溃。
1.可用的软件包和工具
对于Web抓取,没有通用的解决方案,因为在每个网站上存储数据的方式通常是特定于该网站的。实际上,如果您要抓取数据,则需要了解网站的结构并构建自己的解决方案或使用高度可定制的解决方案。
但是,您不需要重新发明轮子:有许多软件包可以为您发挥最大的作用。根据您的编程技能和预期的用例,您可能会发现或多或少有用的不同软件包。
1.1检查选项
大多数时候,您会发现自己在检查HTML网站。您可以使用Bowser的“检查”选项轻松完成此操作。
网站上保存着我的名字,头像和描述的部分被称为hero hero--profile u-flexTOP。名为我的类被调用ui-h2 hero-title,并且描述包含在类中ui-body hero-description。
1.2cra
有一个名为Scrapy的独立的随时可用的数据提取框架。除了提取HTML之外,该程序包还提供许多功能,例如以格式导出数据,记录日志等。它还可以高度自定义:在不同的进程上运行不同的Spider,禁用Cookies¹并设置下载延迟²。它也可以用于使用API提取数据。但是,对于新程序员来说,学习曲线并不顺利:您需要阅读教程和示例才能上手。
· 有些网站使用Cookie来识别机器人。
· 由于大量抓取请求,网站可能超载。
对于我的用例,它太“开箱即用”:我只想从所有页面中提取链接,访问每个链接并从中提取信息。
1.3带有请求的BeautifulSoup
BeautifulSoup是一个库,可让您以优美的方式解析HTML源代码。同时,您需要一个请求库,该库将获取URL的内容。但是,您应该注意所有其他事项,例如错误处理,如何导出数据,如何并行化Web抓取工具等。
我选择BeautifulSoup是因为它会迫使我找出Scrapy自己处理的许多内容,并希望可以帮助我从错误中更快地学习。
2.基本代码
开始抓取网站非常简单。大多数时候,您会发现自己在检查网站的HTML以访问所需的类和ID。假设我们具有以下html结构,并且我们希望提取main_price元素。注意:discounted_price元素是可选的。
<body>
<div id =“ listings_prices”>
<div class =“ item”>
<li class =“ item_name”>手表</ li>
<div class =“ main_price”>价格:66.68美元</ div>
<div class =“折扣价格:46.68美元</ div>
</ div>
<div class =” item“>
<li class =” item_name“> Watch2 </ li>
<div class =” main_price“>价格:56.68美元< / div>
</ div>
</ div>
</ body>
基本代码是导入库,执行请求,解析html,然后找到class main_price。
有可能出现class main_price在网站的其他部分。为了避免class main_price从网页的任何其他部分提取不必要的内容,我们可以先解决id listings_prices,然后再使用查找所有元素class main_price。
3.陷阱
3.1检查robots.txt
网站的抓取规则可在robots.txt文件中找到。您可以通过在主域名。例如,之后编写robots.txt来找到它。这些规则确定不允许自动提取网站的哪些部分,或者允许漫游器多久请求一次页面。大多数人都不在乎它,但是即使您不打算遵守这些规则,也要尽量保持尊重并至少看一下这些规则。
3.2 HTML可能是邪恶的
HTML标记可以包含id,class或两者。HTML id指定唯一的ID,HTML类是唯一的。类名或元素的更改可能会破坏您的代码或提供错误的结果。
有两种方法可以避免它,或者至少要对其进行提醒:
· 使用特定的id而不是class因为它不太可能被更改;
· 检查元素是否返回 None。
但是,由于某些字段是可选的(例如discounted_price在我们的HTML示例中),因此相应的元素不会出现在每个列表中。在这种情况下,您可以计算此特定元素返回“无”的次数占列表数量的百分比。如果是100%,则可能要检查元素名称是否已更改。
3.3用户代理欺骗
每次您访问网站时,它都会通过用户代理获取浏览器信息。除非您提供用户代理,否则某些网站不会向您显示任何内容。另外,某些站点向不同的浏览器提供不同的内容。网站不想阻止真正的用户,但是如果您使用相同的用户代理每秒发送200个请求,您就会感到可疑。一种解决方法是要么生成几乎随机用户代理,要么自行设置。
3.4超时请求
默认情况下,Request将无限期地等待响应。因此,建议设置超时参数。
3.5我被封锁了吗
频繁出现状态代码,例如404(未找到),403(禁止),408(请求超时),可能表明您已被阻止。您可能需要检查这些错误代码,然后进行相应处理。
另外,准备处理请求中的异常。
3.6 IP轮换
即使您将用户代理随机化,所有请求都将来自同一IP地址。这听起来并不异常,因为图书馆,大学以及公司只有几个IP地址。但是,如果通常有多个请求来自单个IP地址,则服务器可以检测到它。使用共享代理,VPN或TOR可以帮助您成为鬼魂。
通过使用共享代理,网站将看到代理服务器的IP地址,而不是您的IP地址。VPN将您连接到另一个网络,并且VPN提供商的IP地址将发送到该网站。
3.7蜜罐
蜜罐是检测爬虫或刮板的手段。
这些可以是用户看不见的“隐藏”链接,但可以由刮板/蜘蛛提取。此类链接的CSS样式设置为display:none,可以通过具有背景色来进行混合,甚至可以移出页面的可见区域。一旦您的搜寻器访问了这样的链接,您的IP地址就可以被标记为进一步调查,甚至被立即阻止。
发现爬网程序的另一种方法是添加具有无限深目录树的链接。然后,将需要限制检索页面的数量或限制遍历深度。
4.做与不做
· 抓取之前,请检查是否有可用的公共API。与网络抓取相比,公共API提供了更轻松,更快(合法)的数据检索。查看提供用于不同目的的API的Twitter API。
· 如果您抓取大量数据,则可能要考虑使用数据库来快速分析或检索它。遵循本教程,了解如何使用python创建本地数据库。
· 讲礼貌。就像这个答案所建议的那样,建议让人们知道您正在抓捕他们的网站,以便他们可以更好地响应您的漫游器可能引起的问题。
同样,不要通过每秒发送数百个请求来使网站超载。
5.加速—并行化
如果决定并行化程序,请谨慎执行,以免猛烈破坏服务器。并且确保您阅读了“注意事项”部分。在此处和此处检查并行化与并发,处理器和线程的定义。
如果您从页面中提取大量信息并在抓取时对数据进行了一些预处理,则发送到页面的每秒请求数可能会相对较低。
对于我另一个刮掉公寓租金价格的项目,我在刮擦时对数据进行了大量预处理,结果是每秒请求1次。为了抓取4K广告,我的程序将运行大约一小时。
为了并行发送请求,您可能需要使用多处理程序包。
假设我们有100个页面,并且我们希望为每个处理器分配相同数量的页面。如果nCPU的数量为,则可以将所有页面平均分块到nbin中,然后将每个bin分配给处理器。每个进程都有其自己的名称,目标函数和要使用的参数。以后可以使用进程名称来将数据写入特定文件。
我为4个CPU分配了1K页,每秒产生4个请求,并将抓取时间减少到大约17分钟。想了解更多关于python的信息,请继续关注。