相同请求下Curl返回不同响应的原因及解决办法
关于LinkedIn两次curl请求响应不一致的问题分析
问题描述
我在Linux命令行用curl访问LinkedIn官网时发现异常,于是运行以下脚本存储并对比两次请求的响应:
# First request curl -o response1.html https://www.linkedin.com/ # Second request sleep 5 curl -o response2.html https://www.linkedin.com/ # Compare icdiff response1.html response2.html
通过icdiff工具发现两次响应存在大量差异,将响应保存为HTML文件后,直观看到登录模块差异尤为明显——第二次响应几乎缺失了完整的登录表单HTML代码(如下):
</div> </div> <!----> <div class="sign-in-form__divider left-right-divider pt-1 pb-3"> <p class="sign-in-form__divider-text font-sans text-sm text-color-text px-2"> or </p> </div> <form data-id="sign-in-form" action="https://www.linkedin.com/uas/login-submit" method="post" novalidate data-js-module-id="d2l-sign-in-form"> <input name="loginCsrfParam" value="a2b3c0d0-9bcf-4d31-8a16-f2a7ceb8011e" type="hidden"> <div class="flex flex-col"> <div class="mt-1.5" data-js-module-id="guest-input"> <div class="flex flex-col"> <label class="input-label mb-1" for="session_key"> Email or phone </label> <div class="text-input flex"> <input class="text-color-text font-sans text-md outline-0 bg-color-transparent grow" autocomplete="username" id="session_key" name="session_key" required data-tracking-control-name="homepage-basic_sign-in-session-key" data-tracking-client-ingraph type="text"> </div> </div> <p class="input-helper mt-1.5" for="session_key" role="alert" data-js-module-id="guest-input__message"></p> </div> <div class="mt-1.5" data-js-module-id="guest-input"> <div class="flex flex-col"> <label class="input-label mb-1" for="session_password"> Password </label> <div class="text-input flex"> <input class="text-color-text font-sans text-md outline-0 bg-color-transparent grow" autocomplete="current-password" id="session_password" name="session_password" required data-tracking-control-name="homepage-basic_sign-in-password" data-tracking-client-ingraph type="password"> <button aria-live="assertive" aria-relevant="text" data-id="sign-in-form__password-visibility-toggle" class="font-sans text-md font-bold text-color-action z-10 ml-[12px] hover:cursor-pointer" aria-label="Show your LinkedIn password" data-tracking-control-name="homepage-basic_sign-in-password-visibility-toggle-btn" type="button"> Show</button> </div> </div> <p class="input-helper mt-1.5" for="session_password" role="alert" data-js-module-id="guest-input__message"></p> </div> <input name="session_redirect" type="hidden"> <!----> </div> <div data-id="sign-in-form__footer" class="flex justify-between sign-in-form__footer--full-width"> <a data-id="sign-in-form__forgot-password" class="font-sans text-md font-bold link leading-regular sign-in-form__forgot-password--full-width" href="https://www.linkedin.com/uas/request-password-reset?trk=homepage-basic_forgot_password" data-tracking-control-name="homepage-basic_forgot_password" data-tracking-will-navigate>Forgot password?</a> <!----> <input name="trk" value="homepage-basic_sign-in-submit" type="hidden"> <button class="btn-md btn-primary flex-shrink-0 cursor-pointer sign-in-form__submit-btn--full-width" data-id="sign-in-form__submit-btn" data-tracking-control-name="homepage-basic_sign-in-submit-btn" data-tracking-client-ingraph data-tracking-litms type="submit"> Sign in </button> </div> <!----> </form> <!---->
两次请求的登录模块视觉差异明显,按常规预期相同请求应得到一致响应,想请教:为何相同请求下响应内容会变化?该现象是否正常?能否解决?
为什么相同请求会出现响应变化?
- 反爬虫机制触发:LinkedIn的系统会识别异常请求模式,连续的无状态curl请求(没有携带浏览器标识、Cookie等)会被判定为潜在爬虫,系统会动态调整返回内容,比如隐藏登录表单来限制自动化操作。
- 动态内容渲染策略:LinkedIn的部分页面内容是基于用户会话、请求频率甚至地理位置动态生成的。第一次请求时系统认为是正常访客,返回完整登录表单;第二次请求因为间隔短且无会话标识,系统触发了不同的渲染逻辑。
- 会话状态缺失:浏览器访问时会自动携带Cookie维持会话,但curl默认是无状态的,每次请求都是全新的会话。LinkedIn的服务器可能会根据会话存在与否返回不同内容,未建立会话的重复请求会被归类为高风险,从而返回简化版页面。
这种现象是否正常?
这属于网站的正常安全防护行为,完全符合主流大型网站的反爬虫和访问控制策略。LinkedIn需要防止自动化工具批量爬取数据、恶意登录尝试等行为,所以会对异常请求动态调整返回内容,保护平台安全和用户数据。
如何解决这个问题?
要让两次请求返回一致内容,需要模拟真实浏览器的请求行为:
- 添加请求头模拟浏览器:在curl命令中加入
User-Agent、Accept等浏览器常用头信息,比如:curl -o response1.html -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36" https://www.linkedin.com/ - 维持会话Cookie:第一次请求后保存Cookie,第二次请求时携带,比如:
# 第一次请求保存Cookie到文件 curl -o response1.html -c cookies.txt -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36" https://www.linkedin.com/ # 第二次请求携带Cookie sleep 5 curl -o response2.html -b cookies.txt -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36" https://www.linkedin.com/ - 控制请求频率:延长两次请求的间隔时间,避免触发频率限制,比如把
sleep 5改成sleep 10或更长。
内容的提问来源于stack exchange,提问作者DarPlays
相关产品推荐
相关产品推荐

