Ruby에서 Amazon API 이상의 고급 검색을 원합니다 (capybara, poltergeist)
13645 단어 루비Capybara아마존poltergeist
amazon-ecs로 상품 검색
require 'amazon/ecs'
res = Amazon::Ecs.item_search("Ruby", response_group: "OfferSummary", country: "jp")
res.first_item.get("OfferSummary/LowestUsedPrice/FormattedPrice")
#=> "¥ ????"
amazon/ecs를 이용하면 대단히 간단하게 Amazon의 상품 검색을 할 수 있어 그 TOP 상품의 ASIN이나 가격, 저자를 취득할 수 있다. 개인적으로 여기가 이해하기 쉽습니다 -> amazon-ecs gem 메모
다만 이 Amazon API는 상세한 검색에는 대응하고 있지 않는 것 같고, 요도바시씨로부터 우연히 찾아낸 상품명
TOTO 토토
YEW350 [휴대형 워슈렛트]
그대로 사이트에서 코피페했을 뿐이므로 이상한 장소에 개행이 들어가 있다. 다만, 이것을 아마존의 사이트에 그대로의 형태로 복사해도
이렇게 단단히 검색 결과를 표시하지만, 위의 gem을 사용하면
require 'amazon/ecs'
res = Amazon::Ecs.item_search("TOTO トートーYEW350 [携帯型ウォシュレット]", response_group: "OfferSummary", country: "jp")
res.total_results
#=> 0
res.first_item.get("OfferSummary/LowestUsedPrice/FormattedPrice")
#=> undefined method `get' for nil:NilClass (NoMethodError)
같은 검색 내용인데 검색 결과는 뭐야! 라고 화가 났습니다.
그래서 실제로 Amazon의 검색 사이트에 상품명을 넣어 결과가 표시된 것 같은 동작을 capybara로 써 실행시켜 보기로 하겠습니다. 단번에 소스 전문이지만, 이런 느낌으로
capybara/poltergeist로 상품 검색
amazon.rbrequire 'capybara'
require 'capybara/dsl'
require 'capybara/poltergeist'
# Capybaraの設定
Capybara.configure do |config|
config.run_server = false
config.current_driver = :poltergeist
config.javascript_driver = :poltergeist
config.default_wait_time = 5
config.default_selector = :xpath
end
Capybara.register_driver :poltergeist do |app|
Capybara::Poltergeist::Driver.new(app, {
js_errors: false,
timeout: 1000,
phantomjs_options: [
'--load-images=no',
'--ignore-ssl-errors=yes',
'--ssl-protocol=any']})
end
module Crawler
class Amazon
include Capybara::DSL
def initialize(pName)
@pName = pName
end
#商品名pNameを引数にAmazonで検索してTopの検索結果のページに遷移
def lookup pName=@pName
page.driver.headers = { "User-Agent" => "Mac Chrome" }
visit URI.escape("http://www.amazon.co.jp/s/ref=nb_sb_noss?__mk_ja_JP=カタカナ&url=search-alias%3Daps&field-keywords=" + pName)
# 検索結果が一つもなかった場合
if page.has_xpath?("//*[@id='noResultsTitle']")
puts "検索結果一つもなし"
return
end
# 検索TOP商品に遷移
visit find(:xpath, "//*[@id='result_0']/div/div[2]/div[1]/a")[:href]
end
#商品ページに来たので、そのASINと最安値を取得する。
def getASIN
puts "#{@pName}のASIN取得中..."
if first('//*[@id="prodDetails"]/div/div[2]/div[1]/div[2]/div/div/table/tbody/tr[1]/td[2]')
asin = first('//*[@id="prodDetails"]/div/div[2]/div[1]/div[2]/div/div/table').text
else
asin = first("//*[@id='detail_bullets_id']/table/tbody/tr/td/div[@class='content']").text
end
if asin =~ /([A-Z0-9]{10})/
asin = $1
end
# 新品の最安値を取得 新品の最安値がなければ正規の価格。それがなければ"0"
lowest_price = first("//*[@id='olp_feature_div']/div/span/span")?
first("//*[@id='olp_feature_div']/div/span/span").text :
(first('//*[@id="priceblock_ourprice"]')? first('//*[@id="priceblock_ourprice"]').text : "0")
lowest_price.gsub!(/[^\d]/, "").to_i
puts asin
puts lowest_price
end
# javascriptロードのための待機時間
def wait_for_ajax
Timeout.timeout(Capybara.default_wait_time) do
loop until page.evaluate_script('jQuery.active').zero?
end
end
end
end
crawler = Crawler::Amazon.new("TOTO トートーYEW350 [携帯型ウォシュレット]")
crawler.lookup # 商品名でAmazon検索したTOP商品のページに遷移
crawler.getASIN # その遷移先のページにあるASINや価格を取得
첫 번째 lookup 함수에서
visit URI.escape("http://www.amazon.co.jp/s/ref=nb_sb_noss?__mk_ja_JP=カタカナ&url=search-alias%3Daps&field-keywords=" + pName)
라고 하고 있어 인간이 검색하도록(듯이) 검색하고 있는 감 일절 없습니다만, 최초의 상품 검색의 부분은 field-keywords의 값이 바뀌고 있을 뿐이었기 때문에 이것으로 검색하고 있는 것처럼 보였습니다. 가장 사람이 검색하도록 검색하고 있는 느낌을 내고 싶다면 이렇게 해도 아마 좋다고 생각합니다
fill_in "field_keywords", :with => "ここに検索する文字列"
find(:xpath, '//*[@id="nav-search"]/form/div[2]/div/input').click
이렇게 하면 name이 field-keywords의 input 부분에 "여기서 검색하는 문자열"을 사람이 입력해 옆의 검색하는 버튼은 name이 없었기 때문에 Xpath로 지정해 줘 클릭한다.
이렇게 천이한 앞의 상품의 ASIN을 취득하는 부분입니다만, 상품에 의해 ASIN이 그려져 있는 부분이 꽤 다르므로 소스 코드안이 잘 모르는 정도로 엉망이 되어 버렸습니다. . 뭔가 좋은 스크레이 핑프 방법을 찾은 분이라면 알려주세요! !
핀 포인트에 Xpath를 지정해도 기재 정보의 양에 따라 li[3]나 li[4]와 같이 장소에 약간의 어긋남이 있었으므로, 대략적으로 그 부분의 텍스트 전부 꺼내고, ASIN이 10자리수 의 영숫자이기 때문에, 매치하는 부분을 빼내고 있습니다만, 만일의 예외 처리라든지 쓰고 있지 않습니다만, 좋으면 사용해 보세요. 이상, 최초의 투고로 깜짝 놀고 있는 사람이었습니다.
Reference
이 문제에 관하여(Ruby에서 Amazon API 이상의 고급 검색을 원합니다 (capybara, poltergeist)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/pokohide/items/ba0acf2fccc23658acf2
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
require 'amazon/ecs'
res = Amazon::Ecs.item_search("Ruby", response_group: "OfferSummary", country: "jp")
res.first_item.get("OfferSummary/LowestUsedPrice/FormattedPrice")
#=> "¥ ????"
require 'amazon/ecs'
res = Amazon::Ecs.item_search("TOTO トートーYEW350 [携帯型ウォシュレット]", response_group: "OfferSummary", country: "jp")
res.total_results
#=> 0
res.first_item.get("OfferSummary/LowestUsedPrice/FormattedPrice")
#=> undefined method `get' for nil:NilClass (NoMethodError)
amazon.rb
require 'capybara'
require 'capybara/dsl'
require 'capybara/poltergeist'
# Capybaraの設定
Capybara.configure do |config|
config.run_server = false
config.current_driver = :poltergeist
config.javascript_driver = :poltergeist
config.default_wait_time = 5
config.default_selector = :xpath
end
Capybara.register_driver :poltergeist do |app|
Capybara::Poltergeist::Driver.new(app, {
js_errors: false,
timeout: 1000,
phantomjs_options: [
'--load-images=no',
'--ignore-ssl-errors=yes',
'--ssl-protocol=any']})
end
module Crawler
class Amazon
include Capybara::DSL
def initialize(pName)
@pName = pName
end
#商品名pNameを引数にAmazonで検索してTopの検索結果のページに遷移
def lookup pName=@pName
page.driver.headers = { "User-Agent" => "Mac Chrome" }
visit URI.escape("http://www.amazon.co.jp/s/ref=nb_sb_noss?__mk_ja_JP=カタカナ&url=search-alias%3Daps&field-keywords=" + pName)
# 検索結果が一つもなかった場合
if page.has_xpath?("//*[@id='noResultsTitle']")
puts "検索結果一つもなし"
return
end
# 検索TOP商品に遷移
visit find(:xpath, "//*[@id='result_0']/div/div[2]/div[1]/a")[:href]
end
#商品ページに来たので、そのASINと最安値を取得する。
def getASIN
puts "#{@pName}のASIN取得中..."
if first('//*[@id="prodDetails"]/div/div[2]/div[1]/div[2]/div/div/table/tbody/tr[1]/td[2]')
asin = first('//*[@id="prodDetails"]/div/div[2]/div[1]/div[2]/div/div/table').text
else
asin = first("//*[@id='detail_bullets_id']/table/tbody/tr/td/div[@class='content']").text
end
if asin =~ /([A-Z0-9]{10})/
asin = $1
end
# 新品の最安値を取得 新品の最安値がなければ正規の価格。それがなければ"0"
lowest_price = first("//*[@id='olp_feature_div']/div/span/span")?
first("//*[@id='olp_feature_div']/div/span/span").text :
(first('//*[@id="priceblock_ourprice"]')? first('//*[@id="priceblock_ourprice"]').text : "0")
lowest_price.gsub!(/[^\d]/, "").to_i
puts asin
puts lowest_price
end
# javascriptロードのための待機時間
def wait_for_ajax
Timeout.timeout(Capybara.default_wait_time) do
loop until page.evaluate_script('jQuery.active').zero?
end
end
end
end
crawler = Crawler::Amazon.new("TOTO トートーYEW350 [携帯型ウォシュレット]")
crawler.lookup # 商品名でAmazon検索したTOP商品のページに遷移
crawler.getASIN # その遷移先のページにあるASINや価格を取得
첫 번째 lookup 함수에서
visit URI.escape("http://www.amazon.co.jp/s/ref=nb_sb_noss?__mk_ja_JP=カタカナ&url=search-alias%3Daps&field-keywords=" + pName)
라고 하고 있어 인간이 검색하도록(듯이) 검색하고 있는 감 일절 없습니다만, 최초의 상품 검색의 부분은 field-keywords의 값이 바뀌고 있을 뿐이었기 때문에 이것으로 검색하고 있는 것처럼 보였습니다. 가장 사람이 검색하도록 검색하고 있는 느낌을 내고 싶다면 이렇게 해도 아마 좋다고 생각합니다
fill_in "field_keywords", :with => "ここに検索する文字列"
find(:xpath, '//*[@id="nav-search"]/form/div[2]/div/input').click
이렇게 하면 name이 field-keywords의 input 부분에 "여기서 검색하는 문자열"을 사람이 입력해 옆의 검색하는 버튼은 name이 없었기 때문에 Xpath로 지정해 줘 클릭한다.
이렇게 천이한 앞의 상품의 ASIN을 취득하는 부분입니다만, 상품에 의해 ASIN이 그려져 있는 부분이 꽤 다르므로 소스 코드안이 잘 모르는 정도로 엉망이 되어 버렸습니다. . 뭔가 좋은 스크레이 핑프 방법을 찾은 분이라면 알려주세요! !
핀 포인트에 Xpath를 지정해도 기재 정보의 양에 따라 li[3]나 li[4]와 같이 장소에 약간의 어긋남이 있었으므로, 대략적으로 그 부분의 텍스트 전부 꺼내고, ASIN이 10자리수 의 영숫자이기 때문에, 매치하는 부분을 빼내고 있습니다만, 만일의 예외 처리라든지 쓰고 있지 않습니다만, 좋으면 사용해 보세요. 이상, 최초의 투고로 깜짝 놀고 있는 사람이었습니다.
Reference
이 문제에 관하여(Ruby에서 Amazon API 이상의 고급 검색을 원합니다 (capybara, poltergeist)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/pokohide/items/ba0acf2fccc23658acf2텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)