HTMLからスクレイピングをするとき、構造が複雑で簡単にタグを指定できない場面に遭遇しました。
まず、スクレイピングしたHTMLの構造は以下のとおりです。
HTML
1<div class="products-mainImg "><img src="/products/products_images/l/PRD2009-09-0046_100012_00_1487742558_58abd4de0e038.png" height="350" width="350" alt=""></div> 2 3<div class="products-detailBox"> 4<div class="products-detailBox__inner"> 5<dl class="products-detailBox__list"> 6<dt class="products-detailBox__term">発売日</dt> 7<dd class="products-detailBox__desc"> 8<table class="products-saleDate" summary="販売地域について:北海道~東海"> 9 <tr> 10 <th>北海道</th> 11 <td>2017年3月<br /></td> 12 </tr> <tr> 13 <th>東北</th> 14 <td>2017年3月<br /></td> 15 </tr> <tr> 16 <th>北関東・信越</th> 17 <td>2017年3月<br /></td> 18 </tr> <tr> 19 <th>首都圏</th> 20 <td>2017年3月<br /></td> 21 </tr> <tr> 22 <th>東海(静岡含む)</th> 23 <td>2017年3月<br /></td> 24 </tr></table> 25<table class="products-saleDate" summary="販売地域について:北陸~沖縄"> 26 <tr> 27 <th>北陸</th> 28 <td>2017年3月<br /></td> 29 </tr> <tr> 30 <th>近畿</th> 31 <td>2017年3月<br /></td> 32 </tr> <tr> 33 <th>中国</th> 34 <td>2017年3月<br /></td> 35 </tr> <tr> 36 <th>四国</th> 37 <td>2017年3月<br /></td> 38 </tr> <tr> 39 <th>九州・沖縄</th> 40 <td>2017年3月<br /></td> 41 </tr></table> 42 43<p class="products-detailBox__areaLink"><a href="#areaBox" class="linkTxt00 js-lightBox">販売地域について</a></p> 44</dd> 45<dt class="products-detailBox__term">内容量</dt> 46<dd class="products-detailBox__desc">135ml</dd> 47<dt class="products-detailBox__term">原材料</dt> 48<dd class="products-detailBox__desc">グレープフルーツ果汁、異性化液糖、食塩/香料、酸味料、甘味料(アスパルテーム・L−フェニルアラニン化合物、スクラロース)、ビタミンC、ポリリン酸Na、カロテン色素</dd> 49<dt class="products-detailBox__term">栄養成分</dt> 50<dd class="products-detailBox__desc">[ 1カップ 当り ]<br />熱量:13kcal<br />たんぱく質:0g<br />脂質:0g<br />炭水化物:3.2g<br />食塩相当量:0.17g<br />ビタミンC:40mg</dd> 51 52<dt class="products-detailBox__term">アレルギー<br>関連情報</dt> 53<dd class="products-detailBox__desc"> 54<p class="products-detailBox__note01"><i class="products-detailBox__icon"><img src="img/detail/icon_material/icon_thumb.png" height="17" width="35" alt=""></i>色のアイコンは原材料に使用されております</p> 55<p class="products-detailBox__stitle">特定原材料</p> 56<ul class="products-detailBox__material"> 57 <li class="products-detailBox__material__item"><img src="img/detail/icon_material/icon_material_0101_off.png" width="60" height="77" alt="卵:不使用"></li> <li class="products-detailBox__material__item"><img src="img/detail/icon_material/icon_material_0102_off.png" width="60" height="77" alt="乳:不使用"></li> <li class="products-detailBox__material__item"><img src="img/detail/icon_material/icon_material_0103_off.png" width="60" height="77" alt="小麦:不使用"></li> <li class="products-detailBox__material__item"><img src="img/detail/icon_material/icon_material_0104_off.png" width="60" height="77" alt="えび:不使用"></li> <li class="products-detailBox__material__item"><img src="img/detail/icon_material/icon_material_0105_off.png" width="60" height="77" alt="かに:不使用"></li> <li class="products-detailBox__material__item"><img src="img/detail/icon_material/icon_material_0106_off.png" width="60" height="77" alt="そば:不使用"></li> <li class="products-detailBox__material__item"><img src="img/detail/icon_material/icon_material_0107_off.png" width="60" height="77" alt="落花生:不使用"></li></ul> 58<p class="products-detailBox__note02">卵・乳を含む製品と共通の設備で製造しています。</p> 59 60<p class="products-detailBox__stitle">特定原材料に準ずるもの</p> 61<ul class="products-detailBox__material"> 62 <li class="products-detailBox__material__item"><img src="img/detail/icon_material/icon_material_0201_off.png" width="60" height="77" alt="あわび:不使用"></li> <li class="products-detailBox__material__item"><img src="img/detail/icon_material/icon_material_0202_off.png" width="60" height="77" alt="いか:不使用"></li> <li class="products-detailBox__material__item"><img src="img/detail/icon_material/icon_material_0203_off.png" width="60" height="77" alt="いくら:不使用"></li> <li class="products-detailBox__material__item"><img src="img/detail/icon_material/icon_material_0204_off.png" width="60" height="77" alt="オレンジ:不使用"></li> <li class="products-detailBox__material__item"><img src="img/detail/icon_material/icon_material_0205_off.png" width="60" height="77" alt="キウイフルーツ:不使用"></li> <li class="products-detailBox__material__item"><img src="img/detail/icon_material/icon_material_0206_off.png" width="60" height="77" alt="牛肉:不使用"></li> <li class="products-detailBox__material__item"><img src="img/detail/icon_material/icon_material_0207_off.png" width="60" height="77" alt="くるみ:不使用"></li> <li class="products-detailBox__material__item"><img src="img/detail/icon_material/icon_material_0208_off.png" width="60" height="77" alt="さけ:不使用"></li> <li class="products-detailBox__material__item"><img src="img/detail/icon_material/icon_material_0209_off.png" width="60" height="77" alt="さば:不使用"></li> <li class="products-detailBox__material__item"><img src="img/detail/icon_material/icon_material_0210_off.png" width="60" height="77" alt="大豆:不使用"></li> <li class="products-detailBox__material__item"><img src="img/detail/icon_material/icon_material_0211_off.png" width="60" height="77" alt="鶏肉:不使用"></li> <li class="products-detailBox__material__item"><img src="img/detail/icon_material/icon_material_0212_off.png" width="60" height="77" alt="バナナ:不使用"></li> <li class="products-detailBox__material__item"><img src="img/detail/icon_material/icon_material_0213_off.png" width="60" height="77" alt="豚肉:不使用"></li> <li class="products-detailBox__material__item"><img src="img/detail/icon_material/icon_material_0214_off.png" width="60" height="77" alt="まつたけ:不使用"></li> <li class="products-detailBox__material__item"><img src="img/detail/icon_material/icon_material_0215_off.png" width="60" height="77" alt="もも:不使用"></li> <li class="products-detailBox__material__item"><img src="img/detail/icon_material/icon_material_0216_off.png" width="60" height="77" alt="やまいも:不使用"></li> <li class="products-detailBox__material__item"><img src="img/detail/icon_material/icon_material_0217_off.png" width="60" height="77" alt="りんご:不使用"></li> <li class="products-detailBox__material__item"><img src="img/detail/icon_material/icon_material_0218_off.png" width="60" height="77" alt="ゼラチン:不使用"></li> <li class="products-detailBox__material__item"><img src="img/detail/icon_material/icon_material_0219_off.png" width="60" height="77" alt="ごま:不使用"></li> <li class="products-detailBox__material__item"><img src="img/detail/icon_material/icon_material_0220_off.png" width="60" height="77" alt="カシューナッツ:不使用"></li></ul> 63 64 65</dd> 66<dt class="products-detailBox__term">製造工場</dt> 67<dd class="products-detailBox__desc">国内で製造しています。</dd> 68<dt class="products-detailBox__term">JANコード</dt> 69<dd class="products-detailBox__desc">4902888341731</dd> 70</dl> 71</div> 72<p class="products-detailBox__txtDate">※2018年01月10日現在の情報です。</p> 73<!-- /.products-detailBox --></div>
長くてすみません。
このうち、上から2番目のdd要素である内容量の<dd class="products-detailBox__desc">135ml</dd>の135mlという情報を取得したいです。
試しに、
serving_size = page.at('.products-detailBox__list dt:nth-child(2) dd').inner_text
追記:以下のコードもだめでした。
serving_size = page.at('dl dt:nth-child(2) dd').inner_text
としてみたのですが、上手く取得できません。
検索してみたのですが、有用な情報がなかったので、おわかりの方がいましたらご教授いただけますと幸いです。
追記:以下にRubyのコードを記載いたします。
require 'mechanize' class Scraping def self.icecream_urls links = [] # 個別ページのリンクを保存する配列 agent = Mechanize.new (1..4).each do |i| current_page = agent.get("http://www.morinaga.co.jp/products/list.php?id=030#{i}") elements = current_page.search('.products__list__item a') elements.each do |ele| links << ele.get_attribute('href') end end links.each do |link| #get_product に引数(個別ページのURL)を渡す get_product('http://www.morinaga.co.jp/products/' + link) end end def self.get_product(link) # 個別ページからアイスの情報を取得する agent = Mechanize.new page = agent.get(link) product_name = page.at('.headingType01__txt').inner_text # 商品名 image_url = page.at('.products-mainImg img').get_attribute('src') # 商品画像 serving_size = page.search('dd:nth-child(13)').inner_text # 内容量 product = Product.where(name: product_name, image_url: image_url, serving_size: serving_size).first_or_initialize product.save end end
可能ならばRubyのコードも全体を載せてもらったほうが、より確実に回答を望めると思います。
コメントありがとうございます。Rubyのコードを追記いたしました。
回答3件
あなたの回答
tips
プレビュー