上一篇我们修改了资料库
并且成功地把BeautifulSoup的资料送到Database内了
今天我们就要来把所有的资料都捞进Database啦
废话不多说,咱们累狗
上一篇我们把单一的公司季财报捞出来了
这边我们准备把所有公司的所有财报捞出来啦
啊对,捞之前记得清Django的Database
今天我们不会进django看看他了
毕竟models views那些东东我们都架好了
今天就只会改BeautifulSoup的部分
首先最重要的,就是先找所有公司代码
这里我们就要改去台湾证券交易所啦
https://www.twse.com.tw/zh/page/listed/listed_company/new_listing.html
这里就是所有上市公司
可是他的预设只有10笔公司怎办呢
没关系,咱们看看上面有"列印/HTML"
这里点进去就可以看到所有公司啦
那这边的url自然就是所有公司的HTML原始码连结啦
废话不多说,捞
import requests
import json
from bs4 import BeautifulSoup
# 所有上市公司列表url
url = 'https://www.twse.com.tw/company/newlisting?response=html&yy='
# 取得所有上市公司原始码
res = requests.get(url=url)
# 用BeautifulSoup分析HTML
soup = BeautifulSoup(res.text, 'html.parser')
# 取得table内容
table_body = soup.find("tbody")
# 将所有公司id存成list
all_comp_id = []
#将每个tr取出
for i in table_body.find_all('tr'):
#取出公司ID
inte = i.find_all('td')[0].getText()
# 6位数代码为存托公司,不在我们分析范围,因此剔除
if int(inte) < 100000:
all_comp_id.append(all_comp_id)
这样我们就把所有公司捞出来啦
接下来就是把公司每季财报捞出来啦
这里我们先回头看原本POST的data
data={
'co_id': '1201',
'queryName': 'co_id',
'inputType': 'co_id',
'isnew': 'true',
'TYPEK': 'all',
'encodeURIComponent': '1',
'step': '1',
'firstin': '1',
'off': '1',
'year': None,
'season': None
}
可以看到co_id就是公司id部分啦
然後这里isnew代表是否直接捞最新财报
这里我们改成false
然後我们捞财报的范围根据查询只有105年~109年的资料
然後109年只有两季
所以我们要写一个回圈去改data内year跟season的
所以我们的data先改写成这样
data={
'co_id': co_id,
'queryName': 'co_id',
'inputType': 'co_id',
'isnew': 'false',
'TYPEK': 'all',
'encodeURIComponent': '1',
'step': '1',
'firstin': '1',
'off': '1',
'year': year,
'season': season
}
然後python有个range可以迭代范围内的数字
记得range含头不含尾
所以我们的回圈写成如下:
for year in range(105, 110): #105含,110不含
season_range = 4 #预设捞四季财报
if year == 109:
season_range = 2 #若是109年则只捞前2
for season in range(1, season_range+1): #从1开始到n
for co_id in all_comp_id: #刚刚存的所有公司id
...
最後有些公司可能是在106年後建立的
所以可能会有找不到财报的情况
就像最知名的八方云集,108年第一季就没有财报
老牌公司味全就有108第一季财报
因此我们万一没捞到财报就要跳过
这特徵也不难找,反正找不到财报时就会跳"查询无资料"
所以我们就设一个条件,如果在汤里面找到"查询无资料"这个字串就跳过
如下面code所示
if bool(soup.findAll(text="查询无资料")):
print("查询无资料")
continue
把以上CODE加上之前写的CODE合并,我们的BeautifulSoup的code部分应该就会变成如下
import requests
import json
from bs4 import BeautifulSoup
#================捞取所有公司part==================
# 所有上市公司列表url
url = 'https://www.twse.com.tw/company/newlisting?response=html&yy='
# 取得所有上市公司原始码
res = requests.get(url=url)
# 用BeautifulSoup分析HTML
soup = BeautifulSoup(res.text, 'html.parser')
# 取得table内容
table_body = soup.find("tbody")
# 将所有公司id存成list
all_comp_id = []
#将每个tr取出
for i in table_body.find_all('tr'):
#取出公司ID
inte = i.find_all('td')[0].getText()
# 6位数代码为存托公司,不在我们分析范围,因此剔除
if int(inte) < 100000:
all_comp_id.append(inte)
#================捞取财报part==================
for year in range(105, 110): #105含,110不含
season_range = 4 #预设捞四季财报
if year == 109:
season_range = 2 #若是109年则只捞前2
for season in range(1, season_range+1): #从1开始到n
for co_id in all_comp_id: #刚刚存的所有公司id
sheet_url = 'https://www.twse.com.tw/company/newlisting?response=html&yy='
data={
'co_id': co_id,
'queryName': 'co_id',
'inputType': 'co_id',
'isnew': 'false',
'TYPEK': 'all',
'encodeURIComponent': '1',
'step': '1',
'firstin': '1',
'off': '1',
'year': 108,
'season': 1
}
headers = {
#'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36',
}
res = requests.post(url=sheet_url,data=data,headers=headers)
soup = BeautifulSoup(res.text, 'html.parser')
#若查询无资料,则显示该公司该年该季度查询无资料之提示,并直接进行下一回圈
if bool(soup.findAll(text="查询无资料")):
print("公司代码:{} {}年{}季 查询无资料".format(comp_id, year ,season))
continue
tr_tag = soup.find_all("tr", {"class": ["odd", "even"]})
data_table = {} #公司财务报表
balance_sheet = {} #负债表
income_statement = {} #损益表
for i in tr_tag:
td_tag = i.find_all("td")
if len(td_tag) == 3: #三个td tag代表为负债表资料
inner = []
for j in td_tag:
inner.append(j.getText())
balance_sheet[inner[0]] = {'金额': inner[1], '百分比': inner[2]}
if len(td_tag) == 5: #五个td tag代表为损益表资料
inner = []
for j in td_tag:
inner.append(j.getText())
income_statement[inner[0]] = {'金额': inner[1], '预测金额': inner[2], '年度财务预测达成率': inner[3], '截至第2季止财务预测季达成率': inner[4]}
url = "http://172.16.15.123:8000/stonks/set_stonks_data/"
data={'comp_id':co_id,
'year':year,
'season':season,
'balance_sheet':json.dumps(balance_sheet),
'income_statement':json.dumps(income_statement)}
res_post = requests.post(url=url,data=data,headers=headers)
#如果回传status code非200,则代表出错,印出该公司该年度该季财报错误
if res_post.status_code != 200:
print("公司代码:{} {}年{}季 存入资料库错误".format(comp_id, year ,season))
#若回传200则提示成功讯息
else:
print("公司代码:{} {}年{}季 存入资料库成功".format(comp_id, year ,season))
最後执行
成功啦~剩下等他自动执行完毕就好了
以上就是自动捞取所有财报的内容啦
然後先预告一下
由於本人明天要回台中
因此下一篇会再做一次中场休息
我们会来讲一下github这个东东,以及如何把你的code丢到github上
想知道如何把你的code存到github这个地方
咱们下回分解~
>>: 【Day17】数据展示元件 - Infinite scroll
函式建构式建立原型 前面几篇有提到,可以使用函示建构式、或是 ES 6 来建立原型,今天就来介绍使用...
嗨~大家好, 接下来是为期一个月的铁人挑战 print('Day_1') 今天是想先跟大家做跟心灵喊...
在我们学习统计学之前应该清楚理解何谓统计学,这样才能够学以致用,并有效利用excel等工具来帮助我们...
原本要使用C3.js搭配D3.js套件制作动态图表,但不知为何一直无法正常抓取D3.js的cdn档案...
Mysql下载 因为网路上已经有很多下载教学了,icebear也是参考网路上下载的,所以在这里就不多...