Как использовать Nokogiri для анализа страницы статистики bit.ly?

Я пытаюсь разобрать имена пользователей Twitter на странице статистики bit.ly с помощью Nokogiri:

require 'rubygems'
require 'nokogiri'
require 'open-uri'

doc = Nokogiri::HTML(open('http://bitly.com/U026ue+/global'))

twitter_accounts = []

shares = doc.xpath('//*[@id="tweets"]/li')

shares.map do |tweet|
  twitter_accounts << tweet.at_css('.conv.tweet.a')
end

puts twitter_accounts

Насколько я понимаю, Нокогири сохранит shares в какой-то форме древовидной структуры, которую я могу использовать для детализации, но мой пробег варьируется.


person Derrick Bradley    schedule 09.12.2012    source источник
comment
Вы уверены, что есть твиты? Когда я запускаю приведенный выше код и проверяю документ, я ничего не вижу.   -  person Eric Walker    schedule 09.12.2012
comment
Я вижу твиты Эрика Уокера.   -  person sunnyrjuneja    schedule 09.12.2012
comment
Вы неправильно используете map в цикле shares.map. Вместо этого должно быть shares.each.   -  person the Tin Man    schedule 09.12.2012
comment
Вы хотите сделать это для любого количества страниц с битовой статистикой или только для этой?   -  person Mark Thomas    schedule 09.12.2012
comment
Марк, я хотел бы иметь возможность сделать это для любой битовой страницы. Эрик, я вижу твиты, но дай мне знать, если проблема не исчезнет... странно.   -  person Derrick Bradley    schedule 10.12.2012


Ответы (2)


Вообще-то, Эрик Уокер что-то понял. Если вы посмотрите на doc, раздел, где должны быть твиты, выглядит так:

<h2>Tweets</h2>
  <ul id="tweets"></ul>
</div>

Вероятно, это связано с тем, что они генерируются некоторым вызовом JavaScript, который Nokogiri не выполняет. Одним из возможных решений является использование watir для перехода на страницу, загрузки JavaScript и последующего сохранения HTML.

Вот скрипт, который выполняет именно это. Обратите внимание, что у вас были некоторые проблемы с вашими аргументами XPath, которые я с тех пор решил, и что watir будет открывать новый браузер каждый раз, когда вы запускаете этот скрипт:

require 'watir'
require 'nokogiri'

browser = Watir::Browser.new
browser.goto 'http://bitly.com/U026ue+/global'

doc = Nokogiri::HTML.parse(browser.html)

twitter_accounts = []

shares = doc.xpath('//li[contains(@class, "tweet")]/a')

shares.each do |tweet|
  twitter_accounts << tweet.attr('title')
end

puts twitter_accounts
browser.close

Вы также можете использовать безголовый, чтобы окно не открывалось.

person sunnyrjuneja    schedule 09.12.2012

Эти данные поступают из запроса Ajax с ответом JSON. Хотя добраться до него довольно легко:

require 'json'
url = 'http://search.twitter.com/search.json?_usragnt=Bitly&include_entities=true&rpp=100&q=nowness.com%2Fday%2F2012%2F12%2F6%2F2643'
hash = JSON.parse open(url).read
puts hash['results'].map{|x| x['from_user']}

Я получил этот URL-адрес, загрузив страницу в Chrome, а затем посмотрев на сетевую панель, я также удалил временную метку и параметры обратного вызова, чтобы немного очистить ситуацию.

person pguardiario    schedule 09.12.2012
comment
Это умное исправление, но я не думаю, что у меня есть способ автоматически получить этот запрос Ajax, не просматривая его вручную в сетевой панели. Это правильно? Это работает, когда вам требуется «open-uri» :) - person Derrick Bradley; 10.12.2012
comment
Конечно. Чтобы создать URL-адрес в своем скрипте, просто найдите значение параметра q (nowness...) в исходном запросе и добавьте его к остальным. - person pguardiario; 10.12.2012