只用 URL 判断两个请求是不是同一个,在 GET 页面上通常够用。可一旦服务器按请求体、语言头或 Cookie 返回不同的内容,URL 相同的请求其实是不同的页面。这篇构造这样的服务器,看四种指纹方案各自漏掉多少。
请求队列共 180 个:40 个商品页 × 2 种语言 = 80;POST /search 20 种请求体 × 重复 3 次 = 60;/account/ 10 个 URL × 2 种 Cookie = 20;/about 重复 10 次;GET /search?q= 10 个 = 10 全部发一遍之后,服务器返回了 131 种不同的内容(真正重复的请求有 49 个)
180 个请求发一遍,服务器返回 131 种不同的内容。其中 49 个是真正的重复(/about 重复 10 次、POST 搜索每个重复 2 次等)。
指纹方案 发出的请求 拿到的不同内容 漏掉的 多发的重复请求 只哈希 URL 62 62 69 0 方法 + URL 62 62 69 0 方法 + URL + 请求体 81 81 50 0 方法 + URL + 请求体 + 关键请求头 131 131 0 0
只哈希 URL 或哈希“方法 + URL”只抓到 62 种,漏掉 69 种;加上请求体 81 种;再加上 Accept-Language 和 Cookie 才是 131 种,不漏也不多发。爬虫的指纹应当包含所有会影响响应的请求要素。
account 带 Cookie:被当成重复丢掉、实际内容不同的请求 10 个 product 带 Accept-Language:被当成重复丢掉、实际内容不同的请求 40 个 search POST:被当成重复丢掉、实际内容不同的请求 19 个
URL 相同、Accept-Language 不同的 40 个商品页;URL 相同、Cookie 不同的 10 个账号页;URL 相同、请求体不同的 19 个 POST 搜索。这些在“只哈希 URL”的指纹下统统被当作重复,没有任何报错。
请求体 'q=word1&page=2' 与 'page=2&q=word1':服务器对两者返回的内容相同吗?True(对本服务器相同);按原始字节哈希的指纹相同吗?False;按解析后排序再哈希的指纹相同吗?True
请求体的参数顺序不同,按原始字节哈希会得到不同的指纹(多抓一次);解析后排序再哈希则相同。这只在服务器对参数顺序不敏感时才合理。把哪些请求头纳入指纹,是个取舍:纳入太多会让指纹碎片化(每个请求头都不同),太少则漏抓。