检测 link 是否无效时出现问题

Problem with detecting if link is invalid

有什么方法可以检测 link 在 python webbot 中是否无效?我需要告诉用户 link 无效,但我不知道如何检测它。

完全确定 url 将您发送到有效页面的唯一方法是获取该页面并检查其是否有效。您 可以 尝试发出 GET 以外的请求来避免浪费带宽下载页面,但并非所有服务器都会响应:唯一绝对确定的方法是 GET 并查看什么发生。类似于:

import requests
from requests.exceptions import ConnectionError

def check_url(url):
    try:
        r = requests.get(url, timeout=1)
        return r.status_code == 200
    except ConnectionError:
        return False

这是个好主意吗?这只是一个 GET 请求,并且 get 应该是幂等的,所以你不应该对任何人造成任何伤害。另一方面,如果用户设置一个脚本以每秒添加一个指向同一网站的新 link 怎么办?然后您正在对该网站进行 DDOSing。因此,当您允许用户导致您的服务器执行此类操作时,您需要考虑如何保护它。 (在这种情况下:您可以保留有效 link 的缓存,每 n 秒过期一次,并且仅在缓存不包含 link 时查找。)

请注意,如果您只想检查 link 指向一个有效的域,这会更容易一些:您可以只进行 dns 查询。 (关于缓存和避免滥用的相同观点可能适用。)

请注意,我使用了请求,因为它很简单,但您可能想在后台执行此操作,或者使用线程中的请求,或者使用 asyncio http 库之一和异步事件环形。否则您的代码将阻塞至少 timeout 秒。

(另一种攻击:这会获取 整个页面 。如果用户 link 访问了一个大页面怎么办?参见 this question 的讨论保护免受超大响应。对于您的用例,您可能只想获得几个字节。我故意不将此处的示例代码复杂化,因为我想说明原理。)

请注意,这只是检查 某些内容 在该页面上是否可用。如果它是重定向到域名网站的众多死 link 之一怎么办?您 可以 强制执行 'no redirects'--- 但是 一些 重定向是有效的。 (同样,您可以尝试检测到主域或供应商域黑名单的重定向,但这总是不完美的。)这里需要权衡,这取决于您的具体用例,但它是值得的意识到。

您可以尝试发送一个 HTTP 请求,打开结果,并获得已知错误代码、404 等的列表。您可以在 Python 中轻松实现此操作,而且高效快捷。请注意,有时(很少)网站可能会检测到您的爬虫并人为地 return 一个错误代码来混淆您。