[PYTHON] Exploration du site Web d'une société de titres

introduction

Récemment, l'exploration est populaire dans la communauté à laquelle j'appartiens, alors j'ai voulu l'essayer moi-même.

Le premier est l'écran cible. スクリーンショット 2019-12-21 9.46.50.png Pouvez-vous ramper seul et vous mettre en colère? Sur ce point, je pense qu'il n'y a pas de problème s'il n'est pas utilisé à des fins commerciales sur aucun site, donc j'aimerais croire que c'est correct. Maintenant, je voudrais explorer l '«indice d'investissement» sur cet écran.

Environnement d'exécution, outils

L'environnement d'exécution est le suivant

$ sw_vers
ProductName:	Mac OS X
ProductVersion:	10.15.1
BuildVersion:	19B88

$ python --version
Python 3.7.4

L'outil continuera à utiliser «Beautiful Soup». Installez le package à partir de la commande pip.

$ pip install beautifulsoup4

D'autres paquets utilisent des «demandes» pour accéder au site.

Connexion, accès à la page

Étant donné que l'écran à explorer nécessite une connexion, implémentez le processus de connexion. Dans le même temps, le traitement d'accès à l'écran cible sera mis en œuvre. C'est comme ça.

app.py


class Scraper():

    def __init__(self, user_id, password):
        self.base_url = "https://site1.sbisec.co.jp/ETGate/"
        self.user_id = user_id
        self.password = password
        self.login()

    def login(self):
        post = {
                'JS_FLG': "0",
                'BW_FLG': "0",
                "_ControlID": "WPLETlgR001Control",
                "_DataStoreID": "DSWPLETlgR001Control",
                "_PageID": "WPLETlgR001Rlgn20",
                "_ActionID": "login",
                "getFlg": "on",
                "allPrmFlg": "on",
                "_ReturnPageInfo": "WPLEThmR001Control/DefaultPID/DefaultAID/DSWPLEThmR001Control",
                "user_id": self.user_id,
                "user_password": self.password
                }
        self.session = requests.Session()
        res = self.session.post(self.base_url, data=post)
        res.encoding = res.apparent_encoding

    def financePage_html(self, ticker):
        post = {
                "_ControlID": "WPLETsiR001Control",
                "_DataStoreID": "DSWPLETsiR001Control",
                "_PageID": "WPLETsiR001Idtl10",
                "getFlg": "on",
                "_ActionID": "stockDetail",
                "s_rkbn": "",
                "s_btype": "",
                "i_stock_sec": "",
                "i_dom_flg": "1",
                "i_exchange_code": "JPN",
                "i_output_type": "0",
                "exchange_code": "TKY",
                "stock_sec_code_mul": str(ticker),
                "ref_from": "1",
                "ref_to": "20",
                "wstm4130_sort_id": "",
                "wstm4130_sort_kbn":  "",
                "qr_keyword": "",
                "qr_suggest": "",
                "qr_sort": ""
                }

        html = self.session.post(self.base_url, data=post)
        html.encoding = html.apparent_encoding
        return html

    def get_fi_param(self, ticker):
        html = self.financePage_html(ticker)
        soup = BeautifulSoup(html.text, 'html.parser')
        print(soup)

ʻExécuter avec l'ID utilisateur, le mot de passeet le numéro de valeur comme arguments. Le processus de connexion et d'accès à la page est facile. J'utilise les informations de publication obtenues à partir de l'URL et du packagerequests. J'ai essayé de sortir le résultat de l'accès sous forme de texte en utilisant la fonction BeautifulSoup (html.text, 'html.parser')` pour vérifier si l'accès était correct.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html lang="ja">
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type"/>
<meta content="text/css" http-equiv="Content-Style-Type"/>
<meta content="text/javascript" http-equiv="Content-Script-Type"/>
<meta content="IE=EmulateIE8" http-equiv="X-UA-Compatible"/><!--gethtml content start-->
<!-- header_domestic_001.html/// -->
・
・
・
<h4 class="fm01"><em>Indice d'investissement</em> 20/09e trimestre (rame)</h4>
</div>
</div>
<div class="mgt5" id="posElem_19-1">
<table border="0" cellpadding="0" cellspacing="0" class="tbl690" style="width: 295px;" summary="Indice d'investissement">
<col style="width:75px;"/>
<col style="width:70px;"/>
<col style="width:80px;"/>
<col style="width:65px;"/>
<tbody>
<tr>
<th><p class="fm01">PER attendu</p></th>
<td><p class="fm01">23.86 fois</p></td>
<th><p class="fm01">BPA attendu</p></th>
<td><p class="fm01">83.9</p></td>
</tr>
<tr>
<th><p class="fm01">Réalisation PBR</p></th>
<td><p class="fm01">5.92 fois</p></td>
<th><p class="fm01">Réalisation BPS</p></th>
<td><p class="fm01">338.33</p></td>
</tr>
<tr>
<th><p class="fm01">Intérêts sur dividendes attendus</p></th>
<td><p class="fm01">0.45%</p></td>
<th><p class="fm01">Dividende attendu d'une action</p></th>
<td><p class="fm01">9〜10</p></td>
・
・
・
</script>
<script language="JavaScript" type="text/javascript">_satellite.pageBottom();</script></body>
</html>

J'ai pu accéder avec succès à l'écran cible et obtenir le HTML sous forme de texte.

Obtenir bloc par bloc depuis HTML

J'ai pu obtenir le HTML sous forme de texte, mais tel qu'il est maintenant, il contient beaucoup de balises et de CSS. Par conséquent, je vais extraire les pièces nécessaires dans l'ordre. Tout d'abord, essayez d'obtenir le bloc qui contient l '«indice d'investissement». Utilisez la fonction find_all () de BeautifulSoup pour obtenir un bloc spécifique. L '«indice d'investissement» est inclus dans les blocs suivants à l'écran. スクリーンショット 2019-12-21 16.27.54.png Ce bloc est dans <div id =" clmSubArea "> sur HTML. Maintenant, spécifions <div id =" clmSubArea "> à la fonction find_all ().

app.py


    def get_fi_param(self, ticker):

        dict_ = {}
        html = self.financePage_html(ticker)
        soup = BeautifulSoup(html.text, 'html.parser')
        div_clmsubarea = soup.find_all('div', {'id': 'clmSubArea'})[0]
        print(div_clmsubarea)

Quand tu fais ça

<div id="clmSubArea">
<div class="mgt10">
<table border="0" cellpadding="0" cellspacing="0" class="tbl02" summary="layout">
<tbody>
・
・
・
<h4 class="fm01"><em>Indice d'investissement</em> 20/09e trimestre (rame)</h4>
</div>
</div>
<div class="mgt5" id="posElem_19-1">
・
・
・
</tr>
</tbody>
</table>
</div>

J'ai pu obtenir le bloc cible.

Obtenir une chaîne

À ce stade, le même travail est répété jusqu'à ce que la chaîne de caractères souhaitée soit obtenue. Faisons tout cela en même temps.

app.py


    def get_fi_param(self, ticker):

        dict_ = {}
        html = self.financePage_html(ticker)
        soup = BeautifulSoup(html.text, 'html.parser')
        div_clmsubarea = soup.find_all('div', {'id': 'clmSubArea'})[0]
        table = div_clmsubarea.find_all('table')[1]
        p_list = table.tbody.find_all('p', {'class': 'fm01'})
        per = p_list[1].string.replace('\n', '')
        print('PER attendu:' + per)

Récupérez le bloc «

» de «l'indice d'investissement» et obtenez tous les «

» qu'il contient. Enfin, si vous obtenez la chaîne de caractères dans <p class =" fm01 ">, le processus est terminé.

$ python -m unittest tests.test -v
test_lambda_handler (tests.test.TestHandlerCase) ...PER attendu:23.86 fois

C'est fait. Après cela, il sera plus facile à utiliser si vous traitez la chaîne de caractères obtenue dans JSON, etc.

À la fin

En utilisant l'exploration, j'ai pu obtenir assez facilement les informations que je souhaitais sur le site. Je pense que c'est une technologie utile à bien des égards si vous conservez correctement la capacité d'utilisation. Je vais rendre ce code compatible avec plusieurs codes titres et le rendre jusqu'au point de cotation sur HTML. S'il y a quelque chose qui peut être produit dans le processus, j'aimerais le décrire à un autre moment.

Recommended Posts

Exploration du site Web d'une société de titres
J'ai essayé de ramper et de gratter le site de courses de chevaux Partie 2
Django Tips-Créez un site de classement avec Django-