Python爬虫中,为什么浏览器动态刷新的数据不会被服务器禁止,而直接请求网址却容易被封?
网址没刷新,价格不停地在跳动,f12 有个 real 开头的 Name,价格就藏在这里。打开找到 Request URL,在 python 里模拟获取,时间长就会出远程主机关闭链接的错误。
问题来了,
1,浏览器的那个 real 里的 Request URL 为什么会不停地自动发送给服务器?
2,python 里把请求 headers 信息填的如果浏览器里面的各种 headers 信息,效果等同于浏览器么?
3,python 里如果搞能搞出像电脑浏览器那样,不会被禁掉,毕竟电脑浏览器也是一直开着网页,也是同一个 ip 在不停地获取数据。
-------------------------------
浏览器里面的 request headers:
:authority:api-ddc.wallstreetcn.com
:method:OPTIONS
:path:/market/info/type?prod_code=DXY.OTC
:scheme:https
accept:/
accept-encoding:gzip, deflate, br
accept-language:zh-CN,zh;q=0.9,zh-TW;q=0.8,en;q=0.7
access-control-request-headers:x-device-id,x-taotie-device-id
access-control-request-method:GET
dnt:1
origin:https://wallstreetcn.com
user-agent:Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36
Python爬虫中,为什么浏览器动态刷新的数据不会被服务器禁止,而直接请求网址却容易被封?
- js 在轮询
2. 如果报文和浏览器报文一样,是等同的,http 是无状态的,这个自己抓包确认下
3. 上 puppeteer 最无脑省事。。不过这是 nodejs 的,python 应该也有相关绑定吧
这是因为浏览器请求和直接请求在请求头、Cookie、JavaScript执行等方面存在关键差异。
浏览器请求会携带完整的请求头(如User-Agent、Accept、Referer等),自动管理Cookie和Session,并执行JavaScript来动态加载内容。而简单的requests.get()通常只发送基本头信息,缺少这些“真实用户”特征,服务器很容易识别为爬虫。
要模拟浏览器,你需要:
- 设置完整的请求头
- 处理Cookie和Session
- 对于JavaScript渲染的内容,使用Selenium或Playwright
import requests
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
'Referer': 'https://www.example.com/',
'Connection': 'keep-alive'
}
session = requests.Session()
response = session.get('https://example.com/data', headers=headers)
对于动态内容,用Selenium:
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get('https://example.com')
# 等待动态加载
element = driver.find_element(By.CLASS_NAME, 'dynamic-content')
简单说就是你的请求要更像真人操作。
UA 和 cookie 以及必要的参数都要一起传过去才行,必要时抓包确认你发的和浏览器发的是不是一样
谢谢,也就是 js 轮询相当于在浏览器里写个 js 代码,按照浏览器的 js 代码里的请求网址?间隔时间?向服务器不停请求数据是吗,那会不会因为请求间隔时间跟代码里的不一样而被对方发现呢?
刚才搜索,看到以下内容,socket 协议能做到服务器自动把数据推动到浏览器显示,我还以为价格刷新用的是这种方法呢。
===================================
数据实时性,你也许会说,如果用户能够每一秒都刷新一下页面,不就实时了?对的。只要每隔多长时间请求一下服务器,就能保证前端数据的实时性。那为什么“服务器总是这么被动的等着被访问呢”?这个问题是关键:因为 http 协议是请求-响应式的。服务器端不会“主动的向客户端发数据”,所以,当服务器有最新数据的时候,无法告知前端,从而前端的数据无法实时。
所以,我们至少有两种方式来解决这个问题:
第一,前端去请求服务器,获取最新数据。
第二,服务器发现有最新数据时,主动发送给客户端。
2:分析一下 [1] 中的两种方法:
第一种方法,其实就是“前端轮询”,前端每隔多长时间去请求一下最新数据。
第二种方法,其实底层已经不再使用 http 协议了,改用 socket 协议了。
分析两者,前者,由于频繁访问服务器,期间创建 http 请求,DNS 解析,服务器处理等过程不断重复,浪费服务器资源。
后者就明显更好。基于 socket 的长连接,避免了多次请求所产生的其他额外资源浪费,更加高效和安全。
本文将对前者进行一个实现,并给出简单实例。后期会对后者进行说明。
---------------------
原文: https://blog.csdn.net/u014290054/article/details/49421621
好的,谢谢,照着浏览器里面的 request headers 信息,一模一样的填进去吧,我没登陆,为什么那里有个 cookie 呢
看错了,这次变成这样了,
:authority:api-ddc.wallstreetcn.com
:method:GET
:path:/market/real?fields=symbol,en_name,prod_name,last_px,px_change,px_change_rate,high_px,low_px,open_px,preclose_px,market_value,turnover_volume,turnover_ratio,turnover_value,dyn_pb_rate,amplitude,dyn_pe,trade_status,circulation_value,update_time,price_precision,week_52_high,week_52_low&prod_code=DXY.OTC
:scheme:https
accept:application/json, text/plain, /
accept-encoding:gzip, deflate, br
accept-language:zh-CN,zh;q=0.9,zh-TW;q=0.8,en;q=0.7
dnt:1
origin:https://wallstreetcn.com
referer:https://wallstreetcn.com/markets/DXY.OTC
user-agent:Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36
x-device-id:pcwscn-166f423e-721d-330a-9417-8d2181d34601
x-taotie-device-id:pcwscn-166f423e-721d-330a-9417-8d2181d34601
下面两行代码,之前没有,
有的网站在你第一次打开的时候发个 cookie,打开不同的页面 cookie 里写入不同的值,你的访问里没有这些值网站就会认为你是爬虫或者是不正确的访问。
刚才确实在某个请求里确实看到了 cookies,不知道为什么消失了,另外,现在多出了两行 x-device-id 跟“ x-taotie-device-id ”,我觉得这是关键,半个小时之前还没有呢,另外,发现请求的 headers 信息总是变来变去,比如跟半年前的就不一样。往深了问,学问太多了。。。
1. 是的,js 在不停地请求
2. 间隔时间,看前端实现,通常不会太频繁,免得给后端造成压力
3. 可能会因为间隔时间和前端 js 不一样而被发现,具体要看后端反爬策略如何实现
4. 前端没有 socket,不过有 websocket,可以做到实时,效果更好,不过浏览器兼容性没有轮询来得好,通常用 socketio 这样的库,带有降级方案。你这里的情况是轮询

