爬行有延迟
快速抓取被认为是一种不好的做法。 不断地访问网站的页面会消耗 CPU 和带宽,而强大的网站会识别您的行为并阻止您的 IP。 如果你运气不好,你可能会收到一封令人讨厌的违反服务条款的信!
爬网程序中延迟请求的技术取决于爬网程序的实现方式。 如果您使用Scrapy,那么您可以设置一个参数来通知爬虫在请求之间等待多长时间。 在一个简单的爬虫中,只需顺序处理列表中的 URL,您可以插入一个 thread.sleep 语句。
如果您实现了分布式爬虫集群来分散页面请求的负载,例如使用具有竞争消费者的消息队列,那么事情可能会变得更加复杂。 这可能有许多不同的解决方案,这超出了本文提供的范围。
如何做
默认情况下,Scrapy 在页面请求之间施加 0 秒的延迟。 也就是说,默认情况下它不会在请求之间等待。
-
这可以使用 DOWNLOAD_DELAY 设置进行控制。 为了进行演示,让我们从命令行运行该脚本:
05 $ scrapy runspider 04_scrape_with_delay.py -s LOG_LEVEL=WARNING Parsing: <200 https://blog.scrapinghub.com> Parsing: <200 https://blog.scrapinghub.com/page/2/> Parsing: <200 https://blog.scrapinghub.com/page/3/> Parsing: <200 https://blog.scrapinghub.com/page/4/> Parsing: <200 https://blog.scrapinghub.com/page/5/> Parsing: <200 https://blog.scrapinghub.com/page/6/> Parsing: <200 https://blog.scrapinghub.com/page/7/> Parsing: <200 https://blog.scrapinghub.com/page/8/> Parsing: <200 https://blog.scrapinghub.com/page/9/> Parsing: <200 https://blog.scrapinghub.com/page/10/> Parsing: <200 https://blog.scrapinghub.com/page/11/> Total run time: 0:00:07.006148 Michaels-iMac-2:05 michaelheydt$
这将爬网 blog.scrapinghub.com 上的所有页面,并报告执行爬网的总时间。 LOG_LEVEL=WARNING 删除大部分日志输出,仅给出 print 语句的输出。 这使用了页面之间的默认等待时间 0,导致抓取时间大约为 7 秒。
-
可以使用 DOWNLOAD_DELAY 设置来设置页面之间的等待。 以下是页面请求之间五秒的延迟:
05 $ scrapy runspider 04_scrape_with_delay.py -s DOWNLOAD_DELAY=5 - s LOG_LEVEL=WARNING Parsing: <200 https://blog.scrapinghub.com> Parsing: <200 https://blog.scrapinghub.com/page/2/> Parsing: <200 https://blog.scrapinghub.com/page/3/> Parsing: <200 https://blog.scrapinghub.com/page/4/> Parsing: <200 https://blog.scrapinghub.com/page/5/> Parsing: <200 https://blog.scrapinghub.com/page/6/> Parsing: <200 https://blog.scrapinghub.com/page/7/> Parsing: <200 https://blog.scrapinghub.com/page/8/> Parsing: <200 https://blog.scrapinghub.com/page/9/> Parsing: <200 https://blog.scrapinghub.com/page/10/> Parsing: <200 https://blog.scrapinghub.com/page/11/> Total run time: 0:01:01.099267
默认情况下,这实际上不会等待 5 秒。 它将等待 DOWNLOAD_DELAY 秒,但等待时间为 DOWNLOAD_DELAY 的 0.5 到 1.5 倍之间的随机因子。 为什么要这样做? 这会让你的爬虫看起来“不那么机器人化”。 您可以使用 RANDOMIZED_DOWNLOAD_DELAY=False 设置来关闭此功能。
工作原理
该爬虫是作为 Scrapy spider 实现的。 类定义首先声明 spider 名称和起始 URL:
class Spider(scrapy.Spider):
name = 'spider'
start_urls = ['https://blog.scrapinghub.com']
parse 方法查找 CSS 'div.prev-post > a',并跟踪这些链接。
scraper 还定义了一个 close 方法,当抓取完成时 Scrapy 会调用该方法:
def close(spider, reason):
start_time = spider.crawler.stats.get_value('start_time')
finish_time = spider.crawler.stats.get_value('finish_time')
print("Total run time: ", finish_time-start_time)
这将访问 spider 爬虫统计对象,检索 spider 的开始和结束时间,并向用户报告差异。