1.目标:获取上交所和深交所所有股票的名称和交易信息;
2. 输出:保存到文件中;
3. 技术路线:requests-bs4-re
1.证券之星:获取所有股票代码列表;
2.网易财经:获取个股信息;
选取原则:股票信息静态存在于HTML页面中,非js代码生成,没有robots协议限制;
1.从证券之星网获取股票列表;
2.根据股票列表逐个到网易财经获取个股信息;
3.将结果存储到文件;
1.获取网页html文本
def getHTMLText(url):
try:
kv = {
'user-agent': 'Mozilla/5.0'} # Mozilla/5.0是一个浏览器的身份标识字段
r = requests.get(url, headers=kv, timeout=30) #模拟浏览器对目标网站发送请求
r.raise_for_status()
r.encoding = r.apparent_encoding
return r.text
except:
return ""
注意:需要模拟浏览器来对目标网站发送请求;
2. 获取所有股票代码数据存进列表中
def getStockList(lst, stockURL):
html = getHTMLText(stockURL) #获取html文本
soup = bs(html, 'html.parser') #解析文本
ul = soup.find('ul', attrs={
"id": "index_data_0"}) #一共有4大类股,此处查找标识为"index_data_0"的沪A股
for a in ul('a'): #遍历ul下的所有a标签
try:
href = a.attrs['href'] #获得a标签中的href属性
stockCode = re.search(r'\d{6}', href).group(0) #由正则表达式匹配href中6位数的代码
if stockCode and stockCode not in lst:
lst.append(stockCode) #将个股加入到列表lst中
except:
continue
3.获取列表中每支股票的详细信息并存入文本文档
def getStockInfo(lst, stockURL, fpath):
with open(fpath, 'w', encoding='utf-8') as obj: #使用w模式
obj.write('')
count = 0
for stock in lst: #遍历列表中的每一支个股
url = stockURL + '0' + stock + '.html' #每一支个股的url
html = getHTMLText(url)
try:
if html == '':
continue #判断是否空页面
infoDict = {
} #用字典存储个股信息
soup = bs(html, 'html.parser') #返回页面解析的信息
div = soup.find('div', attrs={
'class': 'relate_stock clearfix'}) #股票信息所在位置
script = div('script') #div中的script标签
info = script[0].string.strip().split(',') #逗号标识分割信息
infoDict['股票名称'] = eval(re.search(r'name\: \'.*\'', info[0]).group(0).split(':')[1]) # name: '浦发银行'
infoDict['股票代码'] = eval(re.search(r'code\: \'\d{6}\'', info[1]).group(0).split(":")[1]) #code: '600000',
infoDict['现价'] = eval(re.search(r'price\: \'.*\'', info[2]).group(0).split(":")[1]) #price: '10.28',
infoDict['涨跌幅'] = re.search(r'change\: \'.*%', info[3]).group(0).split("'")[1] #change: '0.19%25',
infoDict['昨收'] = eval(re.search(r'yesteday\: \'.*\'', info[4]).group(0).split(":")[1]) #yesteday: '10.26',
infoDict['今开'] = eval(re.search(r'today\: \'.*\'', info[5]).group(0).split(":")[1]) #today: '10.21',
infoDict['最高'] = eval(re.search(r'high\: \'.*\'', info[6]).group(0).split(":")[1]) #high: '10.41',
infoDict['最低'] = eval(re.search(r'low\: \'.*\'', info[7]).group(0).split(":")[1]) #low: '10.12',
with open(fpath, 'a', encoding='utf-8') as obj:
obj.write(str(infoDict) + '\n')
count += 1
print("\r当前进度:{:.2f}%".format(count * 100 / len(lst)), end="") #持续计数并转换显示为数据爬取进度
except:
traceback.print_exc()
print("\r当前进度:{:.2f}%".format(count * 100 / len(lst)), end="")
continue
4.主函数
def main():
tick1 = time.time() #返回当前时间
stock_list_url = "http://quote.stockstar.com/stock/stock_index.htm" #获取所有股票列表的链接
stock_info_url = "http://quotes.money.163.com/" #获取个股信息的链接
outputPath = 'D:\\stockData.txt' #你所希望列表信息存储的位置
slist = []
getStockList(slist, stock_list_url) #获取股票列表
getStockInfo(slist, stock_info_url, outputPath) #获取个股信息
tick2 = time.time() #再次返回当前时间
interval = tick2 - tick1 #得到总共爬取时间
if interval > 60:
print("\n程序运行了{0:.2f}分钟".format(interval / 60)) #转换为分钟显示
else:
print("\n程序运行了{0:.2f}秒".format(interval))
main()
5.总代码
import re
import time
import traceback
import requests
from bs4 import BeautifulSoup as bs
# 获取网页html文本
def getHTMLText(url):
try:
kv = {
'user-agent': 'Mozilla/5.0'} # Mozilla/5.0是一个浏览器的身份标识字段
r = requests.get(url, headers=kv, timeout=30) #模拟浏览器对目标网站发送请求
r.raise_for_status()
r.encoding = r.apparent_encoding
return r.text
except:
return ""
# 获取所有股票代码数据存进列表中
def getStockList(lst, stockURL):
html = getHTMLText(stockURL) #获取html文本
soup = bs(html, 'html.parser') #解析文本
ul = soup.find('ul', attrs={
"id": "index_data_0"}) #一共有4大类股,此处查找标识为"index_data_0"的沪A股
for a in ul('a'): #遍历ul下的所有a标签
try:
href = a.attrs['href'] #获得a标签中的href属性
stockCode = re.search(r'\d{6}', href).group(0) #由正则表达式匹配href中6位数的代码
if stockCode and stockCode not in lst:
lst.append(stockCode) #将个股加入到列表lst中
except:
continue
# 获取列表中每支股票的详细信息并存入文本文档
def getStockInfo(lst, stockURL, fpath):
with open(fpath, 'w', encoding='utf-8') as obj: #使用w模式
obj.write('')
count = 0
for stock in lst: #遍历列表中的每一支个股
url = stockURL + '0' + stock + '.html' #每一支个股的url
html = getHTMLText(url)
try:
if html == '':
continue #判断是否空页面
infoDict = {
} #用字典存储个股信息
soup = bs(html, 'html.parser') #返回页面解析的信息
div = soup.find('div', attrs={
'class': 'relate_stock clearfix'}) #股票信息所在位置
script = div('script') #div中的script标签
info = script[0].string.strip().split(',') #逗号标识分割信息
infoDict['股票名称'] = eval(re.search(r'name\: \'.*\'', info[0]).group(0).split(':')[1]) # name: '浦发银行'
infoDict['股票代码'] = eval(re.search(r'code\: \'\d{6}\'', info[1]).group(0).split(":")[1]) #code: '600000',
infoDict['现价'] = eval(re.search(r'price\: \'.*\'', info[2]).group(0).split(":")[1]) #price: '10.28',
infoDict['涨跌幅'] = re.search(r'change\: \'.*%', info[3]).group(0).split("'")[1] #change: '0.19%25',
infoDict['昨收'] = eval(re.search(r'yesteday\: \'.*\'', info[4]).group(0).split(":")[1]) #yesteday: '10.26',
infoDict['今开'] = eval(re.search(r'today\: \'.*\'', info[5]).group(0).split(":")[1]) #today: '10.21',
infoDict['最高'] = eval(re.search(r'high\: \'.*\'', info[6]).group(0).split(":")[1]) #high: '10.41',
infoDict['最低'] = eval(re.search(r'low\: \'.*\'', info[7]).group(0).split(":")[1]) #low: '10.12',
with open(fpath, 'a', encoding='utf-8') as obj:
obj.write(str(infoDict) + '\n')
count += 1
print("\r当前进度:{:.2f}%".format(count * 100 / len(lst)), end="") #持续计数并转换显示为数据爬取进度
except:
traceback.print_exc()
print("\r当前进度:{:.2f}%".format(count * 100 / len(lst)), end="")
continue
#主函数
def main():
tick1 = time.time() #返回当前时间
stock_list_url = "http://quote.stockstar.com/stock/stock_index.htm" #获取所有股票列表的链接
stock_info_url = "http://quotes.money.163.com/" #获取个股信息的链接
outputPath = 'D:\\stockData.txt' #你所希望列表信息存储的位置
slist = []
getStockList(slist, stock_list_url) #获取股票列表
getStockInfo(slist, stock_info_url, outputPath) #获取个股信息
tick2 = time.time() #再次返回当前时间
interval = tick2 - tick1 #得到总共爬取时间
if interval > 60:
print("\n程序运行了{0:.2f}分钟".format(interval / 60)) #转换为分钟显示
else:
print("\n程序运行了{0:.2f}秒".format(interval))
main()
6.爬取结果
当前进度:100.00%
程序运行了26.20分钟
Process finished with exit code 0