• 締切済み

pythonでスクレイピングがうまく出来ません

python2.7でbeautifulsoupを用いて、netkeiba.comから競馬情報(騎手の成績)をスクレイピングしています。 定法に基づきまして、『検証』からページのツリー構造を把握して、プログラムを作成しました。 馬名部分の構造が<td class="txt_l"> <a href="/horse/2011105901">テンテマリ</a></td> #テンテマリは馬名 となっておりましたので、"txt_l"を拾い出せるようにスクリプトを作りました。 しかしながら、 馬名以外の"txt_l"は全部スクレイピング出来るのですが、馬名部分だけがNoneと返ってまいります。 エラーメッセージではありませんが、何が原因でNoneとなるのかが、どうしても分かりません。 ちなみに、馬名以外で、ほぼ同様の構造を持つ、『レース名』、構造は <td class="bml txt_l"> <a href="/race/201603020812/" title="3歳上500万円下">3歳上500万円下</a> (3歳上500万円下はレース名) では、問題なくレース名を拾うことが出来ました。 該当のソースコード -*- coding:utf-8 -*- import urllib2 import codecs from bs4 import BeautifulSoup tpl_url='http://db.netkeiba.com/?pid=jockey_detail&id=00663&page={0}' for i in xrange( 1, 2 ): url=tpl_url.format( i ) soup = BeautifulSoup(urllib2.urlopen(url).read(),"lxml") tr_arr = soup.find('div', {'id':'contents_liquid'}).findAll('tbody') for tr in tr_arr: lrg1 = tr.findAll('td',{'class':'txt_l'}) for tr1 in lrg1: print tr1.string 試したこと 馬名以外の('td',{'class':'txt_l'})に準ずる『レース名』は、うまく拾うことが出来ました。 lrg1 = tr.findAll('td',{'class':'txt_l'}) で馬名を得ることが出来ない理由、併せて馬名を拾えるスクリプトを御教示くださいますよう、よろしくお願いいたします!

みんなの回答

回答No.1

最後の行の print tr1.string を print tr1.a.string にするとできます。 tdタグの中にまだaタグがあるのでNoneになります。 print tr1.get_text().strip() にするとタグ内のテキストを出力できます

akakage13
質問者

お礼

おはようございます!目から鱗です!!! 大変助かりました!本当にありがとうございました!!!

関連するQ&A

  • python,bs4でスクレイピング出来ません

    **お世話になります、python初心者ですpython2.7,beautifulsoupを用いて、競馬データをスクレイピングしておりますが、どうにも困っております。 1行だけはprintすることが出来るのですが、20行をスクレイピングするスクリプトと、併せて、CSVに出力させるスクリプトが分かりません。 ** 発生している問題・エラーメッセージ **csvに保存が出来ないこと 20行をまとめてスクレイピングすることが出来ないこと` ** ###該当のソースコード python2.7 -*- coding:utf-8 -*- import urllib2 import codecs from bs4 import BeautifulSoup f = codecs.open('horse.csv', 'w', 'utf-8') f.write('race_date,kaisai,weather,race_number,race_name,tousuu,frame_number,horse_number,single_win_ratio,popularity,horse_arrival,horse_name,weight,distance,baba, race_time,difference,horse_pass,pace,nobori,horse_weight,win_horse,prize_money'+ u"\n") tpl_url='http://db.netkeiba.com/?pid=jockey_detail&id=00663&page={0}' for i in xrange(1, 5): url=tpl_url.format( i ) soup = BeautifulSoup(urllib2.urlopen(url).read(),"lxml") tr_arr = soup.find('div', {'id':'contents_liquid'}).findAll('tbody') for tr in tr_arr: 日付#race_date lrg1= tr.findAll('td')[0].string 開催#kaisai lrg2= tr.findAll('td')[1].string 天気#weather lrg3= tr.findAll('td')[2].string 第○レース#race_number lrg4= tr.findAll('td')[3].string レース名#race_name lrg5= tr.findAll('td')[4].string 映像(この部分、削除したいです) lrg6= tr.findAll('td')[5].string 頭数#tousuu lrg7= tr.findAll('td')[6].string 枠番#frame_number lrg8= tr.findAll('td')[7].string 馬番#horse_number lrg9= tr.findAll('td')[8].string 単勝#single_win_racio lrg10= tr.findAll('td')[9].string 人気#popularity lrg11= tr.findAll('td')[10].string 着順#horse_arrival lrg12= tr.findAll('td')[11].string 馬名#horse_name lrg13= tr.findAll('td',{'class':'txt_l'}) [1] 斤量#weight lrg14= tr.findAll('td')[13].string 距離#distance lrg15= tr.findAll('td')[14].string 馬場#baba lrg16= tr.findAll('td')[15].string タイム#race_time lrg17= tr.findAll('td')[16].string 着差#difference lrg18= tr.findAll('td')[17].string 通過#horse_pass lrg19= tr.findAll('td')[18].string ペース#pace lrg20= tr.findAll('td')[19].string 上り#nobori lrg21= tr.findAll('td')[20].string 馬体重#horse_weight lrg22= tr.findAll('td')[21].string 勝ち馬#win_horse lrg23= tr.findAll('td',{'class':'txt_l'}) [2] 賞金#prize_money lrg24= tr.findAll('td')[23].string print lrg1,lrg2,lrg3,lrg4,lrg5,lrg6,lrg7,lrg8,lrg9,lrg10,\ lrg11,lrg12,lrg13.a.string,lrg14,lrg15,lrg16,lrg17,\ lrg18,lrg19,lrg20,lrg21,lrg22,lrg23.a.string,lrg24 f.close() (参考)下記のコードが苦慮しておりますスクレイピング対象のHTMLの 最初の1行部分でございます。 開催日毎に、これが1つのページに、20行、連続してございます。 1行しか捕らえられず、困っております。 <tbody> <tr class=""> <td><a href="/race/list/20160807/">2016/08/07</a></td> <td><a href="/race/sum/04/20160807/">2新潟4</a></td> <td>晴</td> <td class="txt_right">12</td> <td class="bml txt_l"><a href="/race/201604020412/" title="3歳上500万下">3歳上500万下</a></td> <td> <a href="/?pid=movie&amp;id=201604020412" target="_blank"><img src="/style/netkeiba.ja/image/icon_douga.png" border="0"></a> </td> <td class="txt_right">15</td> <td class="txt_right">7</td> <td class="txt_right">13</td> <td class="r3ml txt_right">6.9</td> <td class="r3ml txt_right">3</td> <td class="r2ml txt_right">2</td> <td class=" txt_l"> <a href="/horse/2013103614/">チェイスダウン</a> </td> <td>54</td> <td>ダ1200</td> <td>良</td> <td class="txt_right">1:11.9</td> <td class="txt_right">0.3</td> <td>8-8</td> <td>34.5-37.1</td> <td class="r1ml">36.6</td> <td>468(+2)</td> <td class=" txt_l"> <a href="/horse/2013101531/">クリムゾンバローズ</a> </td> <td>300.0</td> 試したこと forなどで、ループさせてみましたが、スキル不足でうまくいきませんでした。 補足情報(言語/FW/ツール等のバージョンなど) python2.7 findAllを多用して、力ずくで作ったプログラムでございます。 先輩の皆様方、御教示よろしくお願いいたします。

  • csvファイルに保存が出来ずに困っています!!

    python初心者でございます。 python2.7,beautifulsoupを用いて競馬情報をスクレイピングしましたが、 作成されたhorse.csvファイルにデータ保存が出来ず、困っております。 csvファイルに保存出来るスクリプトを、御教示よろしくお願いいたします。 小生が作成したソースコード -*- coding:utf-8 -*- import urllib2 import codecs from bs4 import BeautifulSoup f = codecs.open('horse.csv', 'w', 'utf-8') f.write('tr1') tpl_url='http://db.netkeiba.com/?pid=jockey_detail&id=00663&page={0}' for i in xrange( 1, 2 ): url=tpl_url.format( i ) soup = BeautifulSoup(urllib2.urlopen(url).read(),"lxml") tr_arr = soup.find('div', {'id':'contents_liquid'}).findAll('tbody') for tr in tr_arr: lrg1 = tr.findAll('td',{'class':'txt_l'}) for tr1 in lrg1: print tr1.a.string f.close() 試したこと 上記のプログラムを動かすと作成されたCSVファイルには何も記録、保存されておりませんでした。 御教示よろしくお願いいたします!!!

  • python スクレイピングでのログインができない

    スクレイピングをするために 下記のようなログインサイトにpythonでログインしたいです。 仮定url ="https://aaaaaaa/signin" <form> <p class="signin-label">ログイン画面</p> <ul class="signin-list"> <li class="signin-item"> <div class="hoge1"> <label class="hoge2">メールアドレス</label><div class="hoge3"> <input id="email" autocomplete="email" class="hoge4" type="email" required=""></div> </div> </li> <li class="signin-item"> <div class="hoge5"> <label class="hoge6">パスワード</label> <div class="hoge7"> <input id="password" autocomplete="new-password" class="hoge8" type="password" required=""></div> </div><p class="txt-right"> <a class="signin-link" href="/d/forgot_password">パスワードをお忘れの方</a></p></li></ul><div class="txt-center"> <button type="submit" class="hoge9">ログイン</button> </div> </form> ★行っているコード import requests from bs4 import BeautifulSoup from urllib.parse import urljoin # メールアドレスとパスワードの指定 MAIL = "aaa@mail.net" PASS = "555" # セッションを開始 session = requests.session() # ログイン login_info = { "email":MAIL, "password":PASS, } # action url_login = "https://aaaaaaa/signin" res = session.post(url_login, data=login_info) res.raise_for_status() # エラーならここで例外を発生させる res.text ※エラー内容 HTTPError: 404 Client Error: Not Found for url:https://aaaaaaa/signin 上記となります。 お知恵拝借いただけないでしょうか。

  • PHPによるスクレイピングについて。

    amazonでapiを使わず、スクレイピングをしたいと考えています。ソースを取得後、取得ソース中の下記部分を正規表現で抽出したいと考えていますが、実行すると、「Array ( [0] => Array ( ) [1] => Array ( ) )」 と表示されてしまいます。どこに問題がありますでしょうか? <a href="http://www.amazon.co.jp/gp/offer-listing/B000JJRWIU/ref=sr_1_olp_9/377-5056805-4862865?ie=UTF8&s=dvd&qid=1330077227&sr=1-9">9 点の全新品/中古品を見る</a> <span class="otherprice">¥ 1,197</span>より</span></td></tr><tr><td class="pointsEarnable"></td></tr><tr><td class="fastTrackList">通常5~7日以内に発送</td></tr> <tr><td class="srListSSS"><span class="srEmphSSS">通常配送無料</span></td></tr> <?php include( "scrape_func2.php" ); $_rawData = getURL( "http://www.amazon.co.jp/%E6%81%8B %E6%84%9B-%E5%A4%96%E5%9B%BD%E6%98%A0%E7%94%BB- DVD/b/ref=bw_ab_562016_5? ie=UTF8&node=589344&pf_rd_p=106708969&pf_rd_s=left- 1&pf_rd_t=101&pf_rd_i=562016&pf_rd_m=AN1VRQENFRJN5&pf_rd_r=1G XM2TY1R5SDE3MA35XJ" ); $_rawData = mb_convert_encoding($_rawData, "SJIS", "ASCII,JIS,UTF-8,EUC-JP,SJIS"); /*<a href="http://www.amazon.co.jp/gp/offer-listingで始まり、</span></td></tr>で終わる部分を抽出*/ preg_match_all("/(<a href=\"http:\/\/www.amazon.co.jp\/gp\/offer-listing <\/span><\/td><\/tr>)/", $_rawData, $match); print_r($match); ?> scrape_func2.php <?php function getURL( $pURL ) { $_data = null; if( $_http = fopen( $pURL, "r" ) ) { while( !feof( $_http ) ) { $_data .= fgets( $_http,1024 ); } fclose( $_http ); } return( $_data ); } ?>

    • ベストアンサー
    • PHP
  • このメルフォタグについて…

    <div id="main"> <BR class="clear"> <h2>Contact</h2> <div class="txt"> <table cellspacing="3" cellpadding="3" border=0> <tr> <td>NAME</td> <td><input name="name" type="text" size="30"></td> </tr> <tr> <td>MAIL</td> <td><input name="mail" type="text" size="30"></td> </tr> <tr> <td>URL</td> <td><input name="url" type="text" value="http://" size="30"></td> </tr> <tr> <td valign="top">COMMENT</td> <td><textarea name="msg" cols="30" rows="5">ご感想や管理人へのお便りはこちら☆</textarea></td> </tr> <tr> <td colspan="2" align="right"> <input type="button" name="submit" value="SUBMIT" class="b"></td> </tr> </table> </div> テンプレートをお借りしたのですが、メルフォタグがこのようになっていました。 が、このままでは使用出来ないので、どこに自分のメアドを入れればいいのか教えて下さい。

  • スクレイピングPHPにおける複数spanについて

    外部のホームページのソースを拾いRSS化するPHPを作成しました。 ***************************************** 外部ホームページ http://hoge.com/index.html ***************************************** <html> <table class="Table100"> <tr> <th class="Name"><h1>えんどう豆</h1></th> <td class="Price">254</td> <td class="maker"> <span class="a1">メーカー</span> <span class="a2">遠藤農園</span> </td> </tr> </table> </html> ***************************************** スクレイピングPHP http://hagedebu.jp/index.php  ***************************************** <?php class SimpleXMLExtended extends SimpleXMLElement { public function addCData($data) { $dom = dom_import_simplexml($this); $dom->appendChild($dom->ownerDocument->createCDATASection($data)); } } $xml = new SimpleXMLExtended('<rss version="2.0"></rss>'); $channel = $xml->addChild('channel'); $channel->addChild('title', 'TEST RSS'); $dom = new DOMDocument; @$dom->loadHTMLFile('http://hoge.com/index.html'); $xpath = new DOMXPath($dom); foreach ($xpath->query('//*[@class="Table100"]') as $node) { $item = $channel->addChild('item'); $item->addChild('description')->addCData(implode('<br>', [ $xpath->evaluate('string(.//*[@class="Name"]/h1)', $node), $xpath->evaluate('string(.//*[@class="Price"])', $node), $xpath->evaluate('string(.//*[@class="maker"]/span)', $node), ])); } header('Content-Type: application/xml; charset=utf-8'); $xml->asXML('php://output'); ************************************************ 問題点 このPHPでは、 えんどう豆 254 メーカー と表示されてしまいます。 <td class="maker"> <span class="a1">メーカー</span> <span class="a2">遠藤農園</span> </td> class="makerに複数のspanが入っているため、2つめのspanを認識しません。 当方が表示させたいのは下記のようにspanを両方とも表示させたいです。 またはひとつしか表示させることができない場合は、「メーカー」ではなく「遠藤農園」を優先表示させたいです。 このように表示させるためにはどうすればよいでしょうか? 希望表示 えんどう豆 254 メーカー 遠藤農園 または えんどう豆 254 遠藤農園 よろしくお願いいたします。

    • ベストアンサー
    • PHP
  • メールフォームで必須項目の仕方

    メールフォームで必須項目を入力しないと送信できないようにするにはどうすればいいでしょうか? 現在は以下のとおりに書いてありますが、必須項目に書いてなくても送信できてしまいます。 <form method="post" action="CGI"> <h3>お問い合わせフォーム</h3> <p>*は必須項目です。</p> <table> <tbody> <tr> <th>お問い合わせ内容*</th> <td><textarea name="お問い合わせ内容" class="l" cols="40" rows="12"></textarea></td> </tr> <tr> <th>お名前(漢字)*</th> <td><input type="text" name="お名前(漢字)" class="m"></td> </tr> <tr> <th>お名前(フリガナ)*</th> <td><input type="text" name="お名前(フリガナ)" class="m"></td> </tr> <tr> <th>E-Mail*</th> <td><input type="text" name="E-mail" class="l"></td> </tr> <tr> <th>電話番号(半角)*</th> <td><input type="text" name="電話番号" class="l"></td> </tr> </tbody> </table> <input type="submit" value="  送信  " class="button"></form> また必須項目が未入力のときにエラーメッセージ(「お名前が未入力です。」など)を出したいのですがどのようにすればいいですか?

    • ベストアンサー
    • CGI
  • スクレイピングした内容をvalue値に入れたい

    下記のようなページがあります。 ++++++++++++++++++++++++++++++++++++++++++ 【http://hoge.ne.jp/index.html】 <html> <table border="1"> <tbody> <tr> <td class="class3">東京</td> </tr> </tbody> </table> </html> ++++++++++++++++++++++++++++++++++++++++++ 【出来たこと】 上記の東京という文字を抜き出すスクレイピングページを作りました。 ****************************************** 【http://hogehoge.com/index.html】 <html> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <script type="text/javascript" src="./js/jquery.xdomainajax.js"></script> <script> url = 'http://hoge.ne.jp/index.html'; $.get(url, function(data){ var content4 = $(data.responseText).find('.class3').text(); $("#text4").text(content4); }); </script> <div id="text4"></div> </html> 結果 → 東京 ************************************** 【出来なかったこと】 これを、<input type="text" name="tx" value="東京"> のような形でフォーム内に取り入れることを考えています。 しかしながら、下記のようにうまくいきません。 ●●だめ その1●● <html> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <script type="text/javascript" src="./js/jquery.xdomainajax.js"></script> <script> url = 'http://hoge.ne.jp/index.html'; $.get(url, function(data){ var content4 = $(data.responseText).find('.class3').text(); $("#text4").text(content4); }); </script> <input type="text" name="tx" value="<div id='text4'></div>"> </html> 結果 → 表示されず ●●だめ その2●● <html> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <script type="text/javascript" src="./js/jquery.xdomainajax.js"></script> <script> url = 'http://hoge.ne.jp/index.html'; $.get(url, function(data){ var content4 = $(data.responseText).find('.class3').text(); $("#text4").text(content4); }); var tx4 = content4; document.write("<input type='text' name='tx' value='" + tx4 + "' />"); </script> </html> 結果 → 表示されず 【お願いしたいこと】 <input type="text" name="tx" value="東京">の形で表示させる方法についてアドバイスいただきたくお願いいたします。

  • Firefoxでテーブルの背景画像が表示されない

    下記のようにテーブルに背景画像を表示させたいのですが、 なぜかFirefoxだけ背景画像が表示されません。(WindowsXP,Firefoxは最新版(1.5.0.7)です) IE,OPERA(ともに最新版)では表示されます。 いろいろと検索したのですが同様の相談は見つからず、自分が根本的にミスをしているのだと思いますが、どうしていいのかわからずに相談した次第です。 .tab{width:502px;margin-bottom:20px;} .01{background:url(img/title.gif) top no-repeat;width:502px;height:32px;padding:0px 0px 4px 20px;} .02{background:url(img/com_top.gif); width:502px;height:10px;} .03{background:url(img/com_middle.gif); width:502px;padding:5px 20px 5px 20px;} .04{background:url(img/com_bottom.gif); width:502px;height:10px;} <table cellpadding="0" cellspacing="0" class="tab"> <tr><td class="01">タイトル</td></tr> <tr><td class="02"></td></tr><tr><td class="03"> サンプルテキストサンプルテキストサンプルテキスト </td></tr><tr><td class="04"></td></tr></table> http://www.isonly.net/~second_blue/n/ ↑実際のページです。 汚いHTMLで申し訳ないのですが、解決方法をご存じの方、ご教示下さい。 よろしくお願いします。

  • VBA エクセルの表をHTML形式のテーブルに変換

    https://tonari-it.com/vba-html-table/ 上記のマクロではCSSが使えない簡単なテーブルタグです。 <table> <tr> <td class=“CSS1”>1</td> <td> <div class=“CSS2”> <div class=“CSS3”> <img> <span class=“CSS4” style="background-image: url(images/abc.png);"></span> </div> <div class=“CSS5”> <div class=“CSS6”>山田 太郎</div> <div class="CSS7”><span>東京</span></div> </div> </div> </td> <td class="CSS8>2000</td> <td class="CSS9”>2000</td> <td class="CSS9”>2000</td> <td class="CSS9”>6000</td> </tr> </table> というふうにやりたいのですが、どうしたら良いでしょうか?

専門家に質問してみよう