免费编程软件「python+pycharm」
链接:https://pan.quark.cn/s/48a86be2fdc0
一、为什么选择东方财富网?
东方财富网是中国领先的金融信息服务平台,其股票行情页面实时更新沪深两市股票数据,包含代码、名称、价格、涨跌幅等关键字段。相比其他财经网站,东方财富网的数据接口更稳定,且未设置严格的反爬虫验证,适合初学者练习爬虫技术。
二、爬取前的准备工作
- 安装必要库
pip install requests beautifulsoup4 pandas matplotlib
requests:发送HTTP请求获取网页内容
BeautifulSoup:解析HTML提取数据
pandas:处理表格数据并保存为CSV
matplotlib:绘制股票数据可视化图表(可选) - 模拟浏览器访问
东方财富网会检测请求头中的User-Agent,若发现是爬虫可能拒绝响应。需在请求中添加浏览器标识:
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
}
三、基础爬取:静态页面解析
- 获取网页内容
import requests
url = "http://quote.***.com/center/gridlist.html#hs_a_board"
response = requests.get(url, headers=headers)
if response.status_code == 200:
html_content = response.text
else:
print("请求失败,状态码:", response.status_code)
- 解析HTML表格
东方财富网的股票数据存储在标签中,每行
from bs4 import BeautifulSoup
soup = BeautifulSoup(html_content, 'html.parser')
table = soup.find('table', {'class': 'table'}) # 定位表格
rows = table.find_all('tr')[1:] # 跳过表头
stock_data = []
for row in rows:
cols = row.find_all('td')
stock_info = {
'代码': cols[0].text.strip(),
'名称': cols[1].text.strip(),
'最新价': cols[2].text.strip(),
'涨跌幅': cols[3].text.strip(),
'成交量(手)': cols[4].text.strip()
}
stock_data.append(stock_info)
- 保存为CSV文件
import pandas as pd
df = pd.DataFrame(stock_data)
df.to_csv('stock_data.csv', index=False, encoding='utf-8')
print("数据已保存至stock_data.csv")
四、进阶技巧:应对动态加载与反爬虫
- 处理动态加载内容
若页面数据通过JavaScript动态加载,静态解析可能获取空值。此时需使用Selenium模拟浏览器行为:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
配置ChromeDriver(需提前下载并设置路径)
driver = webdriver.Chrome(service=Service('path/to/chromedriver'))
driver.get(url)
等待页面加载完成(显式等待更可靠)
driver.implicitly_wait(10)
提取数据(示例:通过XPath定位)
stock_elements = driver.find_elements(By.XPATH, '//table[@class="table"]//tr[position()>1]')
stock_data = []
for element in stock_elements:
cols = element.find_elements(By.TAG_NAME, 'td')
stock_info = {
'代码': cols[0].text,
'名称': cols[1].text,
'最新价': cols[2].text
}
stock_data.append(stock_info)
driver.quit()
- 反爬虫应对策略
(1)IP封禁解决方案
代理池:使用免费或付费代理IP轮换请求。
proxies = {
'http': 'http://10.10.10.10:8080',
'https': 'https://10.10.10.10:8080'
}
response = requests.get(url, headers=headers, proxies=proxies)
住宅代理:推荐使用站大爷IP代理等服务商,模拟真实用户IP。
(2)请求频率控制
避免短时间内发送大量请求,可通过time.sleep()添加延迟:
from fake_useragent import UserAgent
ua = UserAgent()
headers = {"User-Agent": ua.random}
(3)随机User-Agent
使用fake_useragent库生成随机浏览器标识:
from fake_useragent import UserAgent
ua = UserAgent()
headers = {"User-Agent": ua.random}
五、数据可视化(可选)
使用matplotlib绘制股票涨跌幅分布图:
import matplotlib.pyplot as plt
转换涨跌幅为数值
df['涨跌幅'] = df['涨跌幅'].str.replace('%', '').astype(float)
绘制直方图
plt.figure(figsize=(10, 6))
plt.hist(df['涨跌幅'], bins=30, color='skyblue', edgecolor='black')
plt.title('股票涨跌幅分布')
plt.xlabel('涨跌幅 (%)')
plt.ylabel('股票数量')
plt.grid(True)
plt.show()
六、完整代码示例
import requests
from bs4 import BeautifulSoup
import pandas as pd
import time
from fake_useragent import UserAgent
def fetch_stock_data():
# 配置请求头
ua = UserAgent()
headers = {"User-Agent": ua.random}
url = "http://quote.***.com/center/gridlist.html#hs_a_board"
try:
# 获取网页内容
response = requests.get(url, headers=headers, timeout=10)
response.raise_for_status()
html_content = response.text
# 解析HTML
soup = BeautifulSoup(html_content, 'html.parser')
table = soup.find('table', {'class': 'table'})
rows = table.find_all('tr')[1:]
# 提取数据
stock_data = []
for row in rows:
cols = row.find_all('td')
stock_info = {
'代码': cols[0].text.strip(),
'名称': cols[1].text.strip(),
'最新价': cols[2].text.strip(),
'涨跌幅': cols[3].text.strip(),
'成交量(手)': cols[4].text.strip()
}
stock_data.append(stock_info)
# 保存为CSV
df = pd.DataFrame(stock_data)
df.to_csv('stock_data.csv', index=False, encoding='utf-8')
print("数据爬取成功,已保存至stock_data.csv")
except Exception as e:
print("爬取失败:", e)
if name == "main":
fetch_stock_data()
七、常见问题Q&A
Q1:被网站封IP怎么办?
A:立即启用备用代理池,建议使用住宅代理(如站大爷IP代理),配合每请求更换IP策略。也可通过requests.proxies参数动态切换代理:
proxies_list = [
{'http': 'http://ip1:port', 'https': 'https://ip1:port'},
{'http': 'http://ip2:port', 'https': 'https://ip2:port'}
]
for proxy in proxies_list:
try:
response = requests.get(url, headers=headers, proxies=proxy, timeout=5)
if response.status_code == 200:
break
except:
continue
Q2:如何获取历史股票数据?
A:东方财富网的历史数据需通过API接口获取,需分析网络请求参数。也可使用第三方库如akshare:
import akshare as ak
df = ak.stock_zh_a_hist(symbol="600519", period="daily", start_date="20240101", end_date="20241231")
df.to_csv("history_data.csv")
Q3:爬取的数据不完整怎么办?
A:检查是否遗漏了动态加载的内容,尝试使用Selenium模拟浏览器操作。若数据通过分页加载,需构造多页URL循环爬取:
base_url = "http://quote.***.com/center/gridlist.html#hs_a_board&pn={}"
all_data = []
for page in range(1, 6): # 爬取前5页
url = base_url.format(page)
response = requests.get(url, headers=headers)
# 解析逻辑同上...
Q4:是否需要登录才能爬取?
A:东方财富网的公开行情数据无需登录,但部分深度数据(如研报)可能需要账号权限。此时需通过requests.Session()维护登录状态:
session = requests.Session()
login_url = "https://passport.***.com/login"
login_data = {"username": "your_username", "password": "your_password"}
session.post(login_url, data=login_data) # 模拟登录
登录后使用session请求数据
response = session.get("目标URL", headers=headers)
八、总结与注意事项
遵守robots协议:爬取前检查https://www.****.com/robots.txt,避免抓取禁止的内容。
控制请求频率:建议每秒不超过1次请求,避免对服务器造成压力。
数据合法使用:仅将爬取的数据用于个人学习或合法研究,不得用于商业盈利。
错误处理:添加异常捕获(如try-except),避免程序因网络问题崩溃。
通过本文的方法,零基础读者也能快速掌握东方财富网股票数据的爬取技巧。随着实践深入,可进一步学习Scrapy框架、分布式爬虫等高级技术。