Skip to content

Instantly share code, notes, and snippets.

@kimihito
Last active January 4, 2016 19:29
Show Gist options
  • Save kimihito/8667565 to your computer and use it in GitHub Desktop.
Save kimihito/8667565 to your computer and use it in GitHub Desktop.
すいませんすいませんすいませんすいません
#!/usr/bin/env ruby
#-*- coding: utf-8 -*-
require 'mechanize'
#お笑いナタリーの芸人プロフィールのページから、芸人の情報を抜き出すスクリプト
#期待するdataの中身
=begin
data =
{
0: {
group_name: "コンビ名",
member: {
0: {
#全部揃っているとは限らない
name: "名前",
birth: "生年月日",
origin: "出身地",
belong: "所属事務所"
},
1: {
name: "名前",
birth: "生年月日",
belong: "所属事務所"
}, ...
}
},
1:{
group_name: "コンビ名",
member: {
....
}
},
....
}
=end
agent = Mechanize.new
page = agent.get('http://natalie.mu/owarai/artist/list/order_by/sort_name')
profile_links = page.links_with(text: 'プロフィール')
data = {}
profile_links.each_with_index do |link,index|
#各芸人のプロフィールを抜き出す
profile_page = link.click
profile = {}
group_name = profile_page.search("div[@id='item-name'] > h2").inner_text
profile[:group_name] = group_name
#プロフィール
members = profile_page.search("div[@id='item-profile'] > p").children().text().gsub("\n", "").split("\r")
member_profile = {}
name_list = members.group_by{ |member|member.include?("●") }[true] #=> ["名前1","名前2"...]
origin_list = members.group_by{ |member|member.include?("出身地") }[true] #=> ["出身地1","出身地2"...]
birth_list = members.group_by{ |member|member.include?("生年月日") }[true] #=> ["生年月日1","生年月日2"...]
belong_list = members.group_by{ |member|member.include?("所属") }[true] #=> ["所属事務所","所属事務所"...]
#member_profileの中身を
=begin
member_profile = {
0: {
#全部揃っているとは限らない
name: "名前",
birth: "生年月日",
origin: "出身地",
belong: "所属事務所"
},
1: {
name: "名前",
birth: "生年月日",
belong: "所属事務所"
}, ...
}
にしたいけど、ここがわからない。
=end
#関連リンク集
links = {}
links_info = profile_page.search("div[@id='item-link'] > ul > li")
links_info.each_with_index do |link,index|
link_data = {}
title = link.text
url = link.search('a').attribute('href').value()
link_data[:title] = title
link_data[:url] = url
links[index.to_s.to_sym] = link_data
end
profile[:links] = links
data[index.to_s.to_sym] = profile
end
@tompng
Copy link

tompng commented Jan 28, 2014

group_by{|a|}[true]select{|a|}って書けますが、どちらにせよデータが一部抜けていた場合
name_list = [田中, 太田]
origin_list = [田中の出身地]
birth_list = [太田の出身地]
となったりしてどうしようもないので、こうならないように処理を変える必要があります。

例1
split(/\r/)で行毎に分ける前に、人毎に分ける

  • split(/●/)
  • scan(/^●[^●]+/)
scan(/^●[^●]+/).each{|person_data|
  lines = person_data.split(/\n/)
  ここで●とか生年月日:とかいろいろしらべる
  member_profile << {name: なまえ, ほげ: ぴよ}
}

例2
eachで回して、●がきたら新しいデータを作るようにする方法もあります

current = nil
each{|line|
  if ●ではじまる
    current = {name: 名前}
    member_profile << current
  else
    current[生年月日とか] = 
  end
}

member_profile は配列のほうが member_profile << でーた とかできて便利だと思います

@tompng
Copy link

tompng commented Jan 28, 2014

メンバー1人しか居ない場合、●なまえがなくて本名:なまえになってますね。これだとscan(/^●[^●]+/)の正規表現使えないですねすみません

@hanachin
Copy link

すごく関係ないけどファイル名たぶんscraping.rbですね

@hanachin
Copy link

フォーマットが統一されてなくてだいぶスクレイピングしづらい感ありますね。
http://natalie.mu/owarai/artist/7398
http://natalie.mu/owarai/artist/6268
http://natalie.mu/owarai/artist/6297

  1. プロフィールページへのリンクが含まれたページを取得
  2. プロフィールページを取得
  3. プロフィールページのフォーマットを見極めていくつかの方法を切り替えながらスクレイピング、謎のフォーマットがあったらログを吐く

みたいな手順を踏むといいのかなと思いました

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment