以下答案是由GPT4-pro回答,本人整理后的结果,如有帮助,还请采纳!
为了实现实时获取WTI原油和其他品种的价格信息,并避免被封禁或触发反爬虫机制,我们可以通过以下方式来模拟正常的浏览器行为,并使用socket
技术进行连接。不过需要说明的是,现代网页通常使用复杂的JavaScript来动态加载数据,这意味着简单的socket
连接可能并不足够,通常需要模拟完整的HTTP请求,甚至处理WebSocket通信。因此,下面的代码会使用socket
模拟一个基础的HTTP请求行为,并间隔5秒抓取数据。
步骤及注意事项:
- 模拟浏览器行为:通过设置请求头,模拟常规浏览器的访问,避免被识别为爬虫。
- socket通信:我们将使用
socket
来模拟HTTP请求。 - 定时获取数据:使用Python中的
time.sleep()
函数来实现每隔5秒获取一次数据。 - 多个网站的数据获取:为每个目标网站都实现独立的socket请求。
- 适当调整请求频率:避免过于频繁的请求被识别为异常流量。
实现步骤及代码:
import socket
import time
# 设置socket请求的函数
def fetch_data_via_socket(host, port, request_headers):
# 创建一个TCP/IP socket连接
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((host, port))
s.sendall(request_headers.encode())
response = s.recv(4096)
return response.decode()
# 获取WTI实时价格信息 (ada)
def fetch_wti_price_ada():
# 目标网站的主机名和端口号
host = 'quote.fx678.com'
port = 80 # HTTP协议默认端口为80
# 构造HTTP请求头,模拟浏览器访问
request_headers = (
"GET /symbol/CONC HTTP/1.1\r\n"
"Host: quote.fx678.com\r\n"
"User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36\r\n"
"Connection: close\r\n\r\n"
)
# 获取数据并返回
return fetch_data_via_socket(host, port, request_headers)
# 获取原油连续实时价格 (adb)
def fetch_oil_continuous_price_adb():
host = 'quote.fx678.com'
port = 80
request_headers = (
"GET /exchange/INE HTTP/1.1\r\n"
"Host: quote.fx678.com\r\n"
"User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36\r\n"
"Connection: close\r\n\r\n"
)
return fetch_data_via_socket(host, port, request_headers)
# 获取纽约原油实时价格信息 (adc)
def fetch_ny_oil_price_adc():
host = 'finance.sina.com.cn'
port = 80
request_headers = (
"GET /futures/quotes/CL.shtml HTTP/1.1\r\n"
"Host: finance.sina.com.cn\r\n"
"User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36\r\n"
"Connection: close\r\n\r\n"
)
return fetch_data_via_socket(host, port, request_headers)
# 获取燃料油连续实时价格 (add)
def fetch_fuel_oil_price_add():
host = 'vip.stock.finance.sina.com.cn'
port = 80
request_headers = (
"GET /quotes_service/view/qihuohangqing.html#titlePos_2 HTTP/1.1\r\n"
"Host: vip.stock.finance.sina.com.cn\r\n"
"User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36\r\n"
"Connection: close\r\n\r\n"
)
return fetch_data_via_socket(host, port, request_headers)
# 主循环,定时获取数据并输出
def main():
while True:
try:
# 获取WTI价格(ada)
wti_price = fetch_wti_price_ada()
print("WTI Price (ada):\n", wti_price)
# 获取原油连续价格(adb)
oil_continuous_price = fetch_oil_continuous_price_adb()
print("Oil Continuous Price (adb):\n", oil_continuous_price)
# 获取纽约原油价格(adc)
ny_oil_price = fetch_ny_oil_price_adc()
print("NY Oil Price (adc):\n", ny_oil_price)
# 获取燃料油连续价格(add)
fuel_oil_price = fetch_fuel_oil_price_add()
print("Fuel Oil Continuous Price (add):\n", fuel_oil_price)
# 每隔5秒获取一次数据
time.sleep(5)
except Exception as e:
print(f"Error: {e}")
break
# 运行主函数
if __name__ == "__main__":
main()
代码解读:
- Socket连接:我们使用
socket
库创建TCP/IP连接,并通过发送HTTP请求头来获取网页的HTML内容。 - 模拟浏览器:通过构造HTTP请求头,特别是
User-Agent
字段,模拟常见的浏览器访问,避免触发反爬虫机制。 - 定时获取数据:在
main
函数中使用time.sleep(5)
实现每隔5秒获取一次数据。 - 可扩展性:每个网站的请求部分已经分开写成了函数。你可以根据需要修改
fetch_*_price
函数中的请求地址和请求头,轻松调整所抓取的数据类型。 - 错误处理:通过
try-except
结构捕获可能的异常,避免程序崩溃。
如何修改品种:
- 如果你想抓取不同的产品或者网站,只需要在相应的
fetch_*_price
函数中修改host
、port
、和request_headers
中的目标URL即可。
注意事项:
- 反爬虫机制:尽管我们通过模拟浏览器请求和适当的间隔时间来减轻爬虫检测的风险,网站可能仍会有更高级的反爬虫策略,例如IP封锁、验证码等。这个方法并不能保证完全规避。
- Socket局限性:某些动态内容(如通过JavaScript加载的数据)可能无法通过简单的socket获取,如果你遇到这种情况,可以考虑使用
Selenium
或requests_html
来模拟完整的浏览器行为。
通过该方案,你应该可以稳定地获取WTI及其他石油品种的实时价格。