一人あたりの利益が高い会社をYahoo!Financeのスクレイピングで調べた

PythonでYahoo!Financeをスクレイピングし,全上場企業を対象に当期利益/従業員数のランキングを作成した.不動産と製薬は強い

http://nbviewer.jupyter.org/github/asterisk37n/notebooks/blob/master/income_per_person.ipynb income_per_person

The Most Net Income per Person of all Companies on Japan Stock Market

Which company is the best? We calculate it by net income per employee. I scraped Yahoo! Finance, Japan to get net income and the number of employees.
In [1]:
%matplotlib inline
import requests
import jsm
from bs4 import BeautifulSoup
import sqlite3
import pandas as pd
In [2]:
# getting all company codes
q = jsm.Quotes()
brands = q.get_brand()
ccodes = []
d = {}
for brand in brands: 
    for com in brands[brand]:
        ccodes.append(com.ccode)
        d[com.ccode] = com.name # to convert compnay code to company name
/home/nwata/anaconda3/lib/python3.6/site-packages/bs4/__init__.py:181: UserWarning: No parser was explicitly specified, so I'm using the best available HTML parser for this system ("lxml"). This usually isn't a problem, but if you run this code on another system, or in a different virtual environment, it may use a different parser and behave differently.

The code that caused this warning is on line 193 of the file /home/nwata/anaconda3/lib/python3.6/runpy.py. To get rid of this warning, change code that looks like this:

 BeautifulSoup([your markup])

to this:

 BeautifulSoup([your markup], "lxml")

  markup_type=markup_type))
In [3]:
def get_profit(ccode):
    r = requests.get('https://profile.yahoo.co.jp/consolidate/{}'.format(ccode))
    bs = BeautifulSoup(r.text, 'lxml')
    text = bs.findAll('td')[39].text
    num = ''.join(s for s in text if s.isdigit())
    return int(num) if num else -1

def get_num_employees(ccode):
    r = requests.get('https://profile.yahoo.co.jp/fundamental/{}'.format(ccode))
    bs = BeautifulSoup(r.text, 'lxml')
    text = bs.findAll('td', attrs = {"width": "25%"})[-1].text
    num = ''.join(s for s in text if s.isdigit())
    return int(num) if num else -1
In [4]:
# iterate through companies. This may take a few minutes.
data = []
for ccode in ccodes:
    pft = get_profit(ccode)
    num = get_num_employees(ccode)
    per = round(pft / num, 2) if pft > 0 and num > 0 else -1
    datum = (ccode, pft, num, per)
    data.append(datum)

print('got net income and employees from {} companies out of {}'.format(len([i for i in data if i[3] > 0]), len(ccodes)))
got net income and employees from 3075 companies out of 3667
In [18]:
# You may want to keep data taken in the above cell into a database.
conn = sqlite3.connect('income_per_person.db')
c = conn.cursor()
c.execute('CREATE TABLE ccodes(ccode TEXT)')
c.executemany('INSERT INTO ccodes VALUES (?)', [(i,) for i in ccodes])
c.execute('CREATE TABLE names(ccode TEXT, name TEXT)')
c.executemany('INSERT INTO names VALUES (?, ?)', [(i, d[i]) for i in ccodes])
c.execute('CREATE TABLE companies(ccode TEXT, net_income INTEGER, employee INTEGER, per_person REAL)')
c.executemany('INSERT INTO companies VALUES (?, ?, ?, ?)', data)
conn.commit()
In [26]:
df_com = pd.io.sql.read_sql_query('SELECT ccode, net_income, employee, per_person FROM companies WHERE per_person > 0 ORDER BY per_person DESC', conn)
df_name = pd.io.sql.read_sql_query('SELECT ccode, name FROM names', conn)
df = df_com.join(df_name.set_index('ccode'), on='ccode')
df
Out[26]:
ccode net_income employee per_person name
0 8925 3094 19 162.84 (株)アルデプロ
1 8918 864 7 123.43 (株)ランド
2 3252 6437 69 93.29 日本商業開発(株)
3 2121 59867 662 90.43 (株)ミクシィ
4 4596 3952 44 89.82 窪田製薬ホールディングス(株)
5 4563 4776 55 86.84 アンジェス(株)
6 8818 3272 43 76.09 京阪神ビルディング(株)
7 8595 11073 152 72.85 (株)ジャフコ
8 1606 23053 339 68.00 日本海洋掘削(株)
9 4565 9797 145 67.57 そーせいグループ(株)
10 2337 14894 240 62.06 いちご(株)
11 3454 2287 40 57.17 ファーストブラザーズ(株)
12 4586 1259 23 54.74 (株)メドレックス
13 4564 3002 55 54.58 オンコセラピー・サイエンス(株)
14 4592 1835 37 49.59 サンバイオ(株)
15 3750 464 10 46.40 セブンシーズホールディングス(株)
16 2134 1008 22 45.82 燦キャピタルマネージメント(株)
17 7776 1414 33 42.85 (株)セルシード
18 3003 34897 827 42.20 ヒューリック(株)
19 8410 25114 637 39.43 (株)セブン銀行
20 8697 42124 1085 38.82 (株)日本取引所グループ
21 4570 2094 54 38.78 (株)免疫生物研究所
22 3777 570 15 38.00 (株)ジオネクスト
23 8890 6523 176 37.06 (株)レーサム
24 9419 693 19 36.47 (株)ワイヤレスゲート
25 7148 7644 211 36.23 (株)FPG
26 4321 10151 293 34.65 ケネディクス(株)
27 3350 1546 46 33.61 (株)レッド・プラネット・ジャパン
28 8836 162 5 32.40 (株)RISE
29 7777 1392 43 32.37 (株)スリー・ディー・マトリックス
... ... ... ... ... ...
3045 1840 30 810 0.04 (株)土屋ホールディングス
3046 5998 67 1914 0.04 (株)アドバネクス
3047 7238 354 9457 0.04 曙ブレーキ工業(株)
3048 7277 82 1884 0.04 (株)TBK
3049 7869 6 170 0.04 日本フォームサービス(株)
3050 4784 21 580 0.04 GMOアドパートナーズ(株)
3051 1408 11 359 0.03 サムシングホールディングス(株)
3052 6424 19 622 0.03 (株)高見沢サイバネティックス
3053 6640 157 5826 0.03 第一精工(株)
3054 7752 3489 105785 0.03 (株)リコー
3055 7923 16 485 0.03 トーイン(株)
3056 3776 9 265 0.03 (株)ブロードバンドタワー
3057 4814 7 230 0.03 ネクストウェア(株)
3058 3346 5 152 0.03 21LADY(株)
3059 2168 243 7144 0.03 (株)パソナグループ
3060 6059 59 1935 0.03 (株)ウチヤマホールディングス
3061 6794 1088 49194 0.02 フォスター電機(株)
3062 9479 9 517 0.02 (株)インプレスホールディングス
3063 7420 12 682 0.02 佐鳥電機(株)
3064 7162 2 84 0.02 アストマックス(株)
3065 4834 6 368 0.02 キャリアバンク(株)
3066 9439 3 174 0.02 (株)エム・エイチ・グループ
3067 9603 267 11364 0.02 (株)エイチ・アイ・エス
3068 5932 94 11246 0.01 三協立山(株)
3069 5950 3 570 0.01 日本パワーファスニング(株)
3070 7781 14 1176 0.01 (株)平山ホールディングス
3071 3393 5 600 0.01 スターティア(株)
3072 8095 8 936 0.01 イワキ(株)
3073 8289 15 1314 0.01 (株)Olympicグループ
3074 2488 3 375 0.01 日本サード・パーティ(株)
3075 rows × 5 columns
In [27]:
df.describe()
Out[27]:
net_income employee per_person
count 3.075000e+03 3075.000000 3075.000000
mean 1.252147e+04 5186.419187 3.305291
std 6.266829e+04 18747.043983 7.308593
min 2.000000e+00 5.000000 0.010000
25% 4.495000e+02 353.000000 0.720000
50% 1.422000e+03 917.000000 1.640000
75% 5.301500e+03 3021.500000 3.240000
max 1.831109e+06 364445.000000 162.840000
In [28]:
ax = df[:10].plot.bar(x='ccode', y='per_person')
ax.set_title('THE 10 COMPANIES WITH THE BIGGEST NET INCOME PER PERSON')
ax.set_xlabel('Companies on stock market')
ax.set_ylabel('Million Japanese Yen')
Out[28]:
<matplotlib.text.Text at 0x7f83301efa90>
In [6]:
conn.close()

コメント