首页 > 解决方案 > node-fetch 返回 403 而 curl 返回 200

问题描述

我正在尝试通过节点获取来解析网页。node-fetch 代码看起来像(AKA,从 chrome 检查器复制):

await fetch('https://www.scottycameron.com/store/user/login/', {
    headers: {
        'authority': 'www.scottycameron.com',
        'upgrade-insecure-requests': '1',
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36',
        'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
        'sec-gpc': '1',
        'sec-fetch-site': 'none',
        'sec-fetch-mode': 'navigate',
        'sec-fetch-user': '?1',
        'sec-fetch-dest': 'document',
        'accept-language': 'en-US,en;q=0.9'
    }
}).then(res => res.text())

请注意,我更改了用户代理以防万一他们关心。这将返回 403 未从 Web 服务器授权。

但是,当我将检查员的请求复制为 curl 并运行它时:

curl 'https://www.scottycameron.com/store/user/login/'   
-H 'authority: www.scottycameron.com'   
-H 'upgrade-insecure-requests: 1'   
-H 'user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'   
-H 'accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9'   
-H 'sec-gpc: 1'   
-H 'sec-fetch-site: none'   
-H 'sec-fetch-mode: navigate'   
-H 'sec-fetch-user: ?1'   
-H 'sec-fetch-dest: document'   
-H 'accept-language: en-US,en;q=0.9'   
--compressed

我得到一个 200 并且返回了预期的 HTML 文档。

我不明白 Web 服务器如何区分我的 node-fetch 和我的 curl 请求,因为它们来自同一个 IP 地址,我知道这不是 IP 白名单问题。我还尝试将调用中存在的 http/v2 标头添加为标头(即从检查器复制 ':authority' 标头并将其添加为 'authority' 标头),但无济于事。

标签: node.jscurlweb-scrapingfetchnode-fetch

解决方案


我最终将 node-libcurl 与 cookiejar 一起使用并修改了 user-agent 标头并解决了这个问题。我不确定为什么 fetch 似乎没有对用户代理标头执行我需要的操作。具体来说,我试图抓取的网站正在四处嗅探并根据一些辅助信息阻止我的流量,而 node-libcurl 使 -v 更容易查看他们使用的包,然后研究如何绕过它。


推荐阅读