控制爬行的深度

爬行的深度可以使用 Scrapy DepthMiddleware 中间件来控制。 深度中间件限制了 Scrapy 从任何给定链接获取的关注数量。 此选项对于控制特定爬网的深度非常有用。 这也可用于防止爬网持续太长时间,如果您知道要爬网的内容位于与爬网开始时的页面一定程度的分离范围内,则此功能非常有用。

如何做

深度控制中间件默认安装在中间件管道中。 深度限制的示例包含在 06/06_limit_depth.py 脚本中。 该脚本在端口 8080 上抓取随源代码提供的静态站点,并允许您配置深度限制。 该站点由三个级别组成:0、1、2,每个级别有三个页面。 这些文件名为 CrawlDepth<level><pagenumber>.html。 每个级别上的页面 1 链接到同一级别上的其他两个页面以及下一个级别上的首页。 到更高级别的链接在级别 2 结束。此结构非常适合检查 Scrapy 中如何处理深度处理。

工作原理

深度的限制可以通过设置 DEPTH_LIMIT 参数来执行:

process = CrawlerProcess({
    'LOG_LEVEL': 'CRITICAL',
    'DEPTH_LIMIT': 2,
    'DEPT_STATS': True
})

深度限制为 1 意味着我们只会抓取一层,这意味着它将处理 start_urls 中指定的 URL,然后处理在这些页面中找到的任何 URL。 使用 DEPTH_LIMIT 我们得到以下输出:

Parsing: <200 http://localhost:8080/CrawlDepth0-1.html>
Requesting crawl of: http://localhost:8080/CrawlDepth0-2.html
Requesting crawl of: http://localhost:8080/Depth1/CrawlDepth1-1.html
Parsing: <200 http://localhost:8080/Depth1/CrawlDepth1-1.html>
Requesting crawl of: http://localhost:8080/Depth1/CrawlDepth1-2.html
Requesting crawl of: http://localhost:8080/Depth1/depth1/CrawlDepth1-2.html
Requesting crawl of: http://localhost:8080/Depth1/depth2/CrawlDepth2-1.html
Parsing: <200 http://localhost:8080/CrawlDepth0-2.html>
Requesting crawl of: http://localhost:8080/CrawlDepth0-3.html
<scrapy.statscollectors.MemoryStatsCollector object at 0x109f754e0>
Crawled: ['http://localhost:8080/CrawlDepth0-1.html',
'http://localhost:8080/Depth1/CrawlDepth1-1.html',
'http://localhost:8080/CrawlDepth0-2.html']
Requested: ['http://localhost:8080/CrawlDepth0-2.html',
'http://localhost:8080/Depth1/CrawlDepth1-1.html',
'http://localhost:8080/Depth1/CrawlDepth1-2.html',
'http://localhost:8080/Depth1/depth1/CrawlDepth1-2.html',
'http://localhost:8080/Depth1/depth2/CrawlDepth2-1.html',
'http://localhost:8080/CrawlDepth0-3.html']

爬网从 CrawlDepth0-1.html 开始。 该页面有两行,一行指向 CrawlDepth0-2.html,一行指向 CrawlDepth1-1.html。 然后要求对它们进行解析。 考虑到起始页面的深度为 0,这些页面的深度为 1,即深度的限制。 因此,我们将看到这两个页面被解析。 但是,请注意,这两个页面的所有链接虽然请求解析,但都会被 Scrapy 忽略,因为它们的深度为 2,超出了指定的限制。

现在将深度限制更改为 2:

process = CrawlerProcess({
    'LOG_LEVEL': 'CRITICAL',
    'DEPTH_LIMIT': 2,
    'DEPT_STATS': True
})

然后输出变为如下:

Parsing: <200 http://localhost:8080/CrawlDepth0-1.html>
Requesting crawl of: http://localhost:8080/CrawlDepth0-2.html
Requesting crawl of: http://localhost:8080/Depth1/CrawlDepth1-1.html
Parsing: <200 http://localhost:8080/Depth1/CrawlDepth1-1.html>
Requesting crawl of: http://localhost:8080/Depth1/CrawlDepth1-2.html
Requesting crawl of: http://localhost:8080/Depth1/depth1/CrawlDepth1-2.html
Requesting crawl of: http://localhost:8080/Depth1/depth2/CrawlDepth2-1.html
Parsing: <200 http://localhost:8080/CrawlDepth0-2.html>
Requesting crawl of: http://localhost:8080/CrawlDepth0-3.html
Parsing: <200 http://localhost:8080/Depth1/depth2/CrawlDepth2-1.html>
Parsing: <200 http://localhost:8080/CrawlDepth0-3.html>
Parsing: <200 http://localhost:8080/Depth1/CrawlDepth1-2.html>
Requesting crawl of: http://localhost:8080/Depth1/CrawlDepth1-3.html
<scrapy.statscollectors.MemoryStatsCollector object at 0x10d3d44e0>
Crawled: ['http://localhost:8080/CrawlDepth0-1.html',
'http://localhost:8080/Depth1/CrawlDepth1-1.html',
'http://localhost:8080/CrawlDepth0-2.html',
'http://localhost:8080/Depth1/depth2/CrawlDepth2-1.html',
'http://localhost:8080/CrawlDepth0-3.html',
'http://localhost:8080/Depth1/CrawlDepth1-2.html']
Requested: ['http://localhost:8080/CrawlDepth0-2.html',
'http://localhost:8080/Depth1/CrawlDepth1-1.html',
'http://localhost:8080/Depth1/CrawlDepth1-2.html',
'http://localhost:8080/Depth1/depth1/CrawlDepth1-2.html',
'http://localhost:8080/Depth1/depth2/CrawlDepth2-1.html',
'http://localhost:8080/CrawlDepth0-3.html',
'http://localhost:8080/Depth1/CrawlDepth1-3.html']

请注意,之前将 DEPTH_LIMIT 设置为 1 时忽略的三个页面现在已被解析。 现在,在该深度找到的链接(例如页面 CrawlDepth1-3.html)现在将被忽略,因为它们的深度超过 2。