“股票数据定向爬虫”实例介绍
功能描述
目标:获取上交所和深交所所有股票的名称和交易信息
输出:保存到文件中
技术路线:requests bs4 re
候选数据网站的选择
新浪股票:http://finance.sina.com.cn/stock/(数据保存在js中,本源码无法爬取)
百度股票:https://gupiao.baidu.com/stock/(已挂)
候选数据网站的选择
选取原则:股票信息静态存在于HTML页面中,非js代码生成,没有Robots协议限制
选取方法:浏览器F12,源代码查看等
选取心态:不要纠结于某个网站,多找信息源尝试
程序的结构设计
步骤1:从东方财富网获取股票列表(2020年也改存在js了)我们这里选取其他网页(天天基金网)
步骤2:根据股票列表逐个到百度股票获取个股信息
步骤3:将结果存储到文件
#查看网页源码
通过网站我们可以看到,https://fund.eastmoney.com/006003.html,每支股票网址是以https://fund.eastmoney.com/+6位数字+.html构成的,接下来我们查看全部股票的网页源码(https://fund.eastmoney.com/fund.html#os_0;isall_0;ft_;pt_1),可以发现,对应股票的所有信息被div标签包围,每支股票对应的6位数字被tr标签包围,<tr id="tr006003">,那我们就可以通过搜寻div标签下的tr标签下的id所对应的个股编号,但是,这里的个股编号是tr+6位数字,而我们只需要6位数字即可,那我们可以通过下标索gp[1:]这样来得到6位数字。在个股网页中,个股的信息内容对应的class类是merchandiseDetail,个股的名称对应的class类是fundDetail-tit
#使用的库
import re
import requests
import traceback
from bs4 import BeautifulSoup
#发起请求的函数
def gethttptext(url,code='utf-8'):
try:
r=requests.get(url,timeout=30)
r.raise_for_status()
r.encoding=code
#print(r.status_code)
return r.text
except:
return ""
#检索网页信息获取股票编号
def getstocklist(list,stockurl):
html=gethttptext(stockurl)
soup=BeautifulSoup(html,'html.parser')
a=soup.find_all('tr')
for i in a:
try:
href=i.attrs['id']
list.append(re.findall(r'[tr]\d{6}',href)[0])
except:
continue
#获取每支股票的信息并保存在txt文件
def getstockinfo(list,stockurl,fpath):
count=0
for stock in list:
url=stockurl+stock[1:]+".html"
html=gethttptext(url)
try:
if html=='':
continue
infodict={}
soup=BeautifulSoup(html,'html.parser')
stockinfo=soup.find('div',attrs={'class':'merchandiseDetail'})
name=stockinfo.find_all(attrs={'class':'fundDetail-tit'})[0]
infodict.update({'股票名称':name.text.split()[0]})
keylist=stockinfo.find_all('dt')
valuelist=stockinfo.find_all('dd')
for i in range(len(keylist)):
key=keylist[i].text
val=valuelist[i].text
infodict[key]=val
with open(fpath,'a',encoding='utf-8') as f:
f.write(str(infodict)+'\n')
count=count+1
print('\r当前速度:{:.2f}%'.format(count*100/len(list)),end='')
except:
count = count + 1
print('\r当前速度:{:.2f}%'.format(count * 100 / len(list)), end='')
traceback.print_exc()
continue
#主函数
if __name__=="__main__":
stock_list_url="https://fund.eastmoney.com/fund.html#os_0;isall_0;ft_;pt_1"
stock_info_url="https://fund.eastmoney.com/"
output_fire="E://py项目//BaiduStockInfo.txt"
slist=[]
getstocklist(slist,stock_list_url)
getstockinfo(slist,stock_info_url,output_fire)
#全部源码
import re
import requests
import traceback
from bs4 import BeautifulSoup
def gethttptext(url,code='utf-8'):
try:
r=requests.get(url,timeout=30)
r.raise_for_status()
r.encoding=code
#print(r.status_code)
return r.text
except:
return ""
def getstocklist(list,stockurl):
html=gethttptext(stockurl)
soup=BeautifulSoup(html,'html.parser')
a=soup.find_all('tr')
for i in a:
try:
href=i.attrs['id']
list.append(re.findall(r'[tr]\d{6}',href)[0])
except:
continue
def getstockinfo(list,stockurl,fpath):
count=0
for stock in list:
url=stockurl+stock[1:]+".html"
html=gethttptext(url)
try:
if html=='':
continue
infodict={}
soup=BeautifulSoup(html,'html.parser')
stockinfo=soup.find('div',attrs={'class':'merchandiseDetail'})
name=stockinfo.find_all(attrs={'class':'fundDetail-tit'})[0]
infodict.update({'股票名称':name.text.split()[0]})
keylist=stockinfo.find_all('dt')
valuelist=stockinfo.find_all('dd')
for i in range(len(keylist)):
key=keylist[i].text
val=valuelist[i].text
infodict[key]=val
with open(fpath,'a',encoding='utf-8') as f:
f.write(str(infodict)+'\n')
count=count+1
print('\r当前速度:{:.2f}%'.format(count*100/len(list)),end='')
except:
count = count + 1
print('\r当前速度:{:.2f}%'.format(count * 100 / len(list)), end='')
traceback.print_exc()
continue
if __name__=="__main__":
stock_list_url="https://fund.eastmoney.com/fund.html#os_0;isall_0;ft_;pt_1"
stock_info_url="https://fund.eastmoney.com/"
output_fire="E://py项目//BaiduStockInfo.txt"
slist=[]
getstocklist(slist,stock_list_url)
getstockinfo(slist,stock_info_url,output_fire)
#输出结果
详见下面网盘链接的BaiduStockInfo.txt文件