我正在尝试通过节点获取来解析网页。节点获取代码看起来像(又名,从 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 '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 文档。
我不明白网络服务器如何区分我的节点获取和我的curl请求,因为它们来自相同的IP地址,我知道这不是IP白名单问题。我还尝试将调用中存在的 http/v2 标头添加为标头(即从检查器复制 ':authority' 标头并将其添加为 'authority' 标头),但无济于事。
我最终使用了带有 cookiejar 的 node-libcurl 并修改了用户代理标头,从而解决了这个问题。我不确定为什么 fetch 似乎没有对用户代理标头执行我需要的操作。具体来说,我试图抓取的网站正在嗅探并根据一些辅助信息阻止我的流量,而 node-libcurl 使 -v 更容易查看他们正在使用什么包,然后研究如何绕过它。