javascript - 计算最后一个工作页面以进行抓取的最快方法
问题描述
我正在尝试抓取一个网站,我不想被迫递归地抓取每个页面,直到“结束”。
我希望能够只获取最后一页,或介于两者之间的任何页面。
大多数时候这不是问题,但这个网页是不同的。例如:
我在“Logitech”上进行搜索查询
该网站返回我要使用的以下信息:
- 找到的产品总数:15.000
- 每页产品:30
- 分页:1、2、3、4、...500 (15.000/30 = 500)
但是,找到的产品总数似乎是虚假信息,分页也是如此,因为当我尝试访问https://website.com/products?q=Logitech&page=500
时没有产品。这也适用于较低的值,例如:499、498、450、400、350 等。
因此,我尝试在脑海中“计算”可能的页码,然后得出实际的最后页码:166
我通过检查是否有结果来“计算”这个:
- 如果有结果:按数量增加值 x
- 如果没有结果:将值递减 x
所以我制作了一个测试脚本来复制我查找页码的方法(repl.it 链接): https ://repl.it/@SaltyPotato1/LastPageCalculator
但我对他的剧本有两个问题(我希望你们能帮助我):
这个脚本“知道”正确的值(166),所以当我抓取时它可以使用
>
和运算符;<
在这种情况下它只能检查是否有结果:产品。这意味着只有 2 个选项:- 如果有结果,则意味着:页码太低 或实际上是最后一个页码。
- 如果没有结果则意味着:页码太高。
我觉得脚本/计算可以改进,因为有些值被发出了两次。
我该怎么做才能确定它是否实际上是最后一页而不是实际最后一页“下方”的页码。我怎样才能最小化计算这个请求的数量。
我期待您的回答/帮助!
解决方案
一般来说,您不应该知道所有类型产品的所有页码。您需要的是使用二进制搜索算法找到正确的最大页数。为此我建议使用HTTP Head请求来检查该路由是否存在,如果服务器不支持该方法,您可以尝试获取请求并仅检查响应的http状态码,这样您就不需要进行复杂的计算/ dom 查询只是为了找出正确的最大页数。
您的代码会有轻微的变化。
function findMaxPageCount(totalProductCount = 1000, productPerPage = 1){
const lo = 1;
const hi = totalProductCount/productPage;
let mid;
let actualMaxPage = -1;
while(lo <= hi){
mid = Math.floor((lo + hi)/2.0);
if(pageExists(mid)){
actualMaxPage = mid;
lo = mid + 1;
}else{
hi = mid - 1;
}
}
return actualMaxPage;
}
上述方法,不会再次搜索同一页面,因此阅读次数最少,最多Math.ceil(log2(totalProductCount/productPage))
。
推荐阅读
- google-bigquery - 将 INT 中的日期转换为 Google Calendar API 的 CreateEvent 的 DateTime
- python - 有没有办法在不使用模型或数据库的情况下在 django 中使用熊猫
- java - 为什么我在线程“main”java.lang.NoClassDefFoundError: com/fasterxml/jackson/core/util/JacksonFeature 在运行时出现异常?
- react-native - React Native - 如何在显示时实时处理相机帧?
- arduino - NodeMCU esptool.FatalError:等待数据包头超时
- python - 如何让 ElementTree.toString 方法输出非中断空间(nbsp)?
- javascript - Chrome mobile:水平滚动不记录
- python - TensorFlow 内存问题
- javascript - 从 NPM 包中引用对象时的 ReferenceError
- python-3.x - 获取名字并存储在字典中的列表中