Я пытаюсь получить информацию о спецификациях для этого сайта:
http://www.gsmarena.com/nokia_lumia_1520-5760.php
В идеале у меня был бы хэш вроде этого:
{'General' => ['2G Network' => 'GSM 850 / 900 / 1800 / 1900 - all versions',
'3G Network' => 'HSDPA 850 / 900 / 1900 / 2100 - RM-937, RM-939, RM-940',
'4G Network' => 'LTE 800 / 900 / 1800 / 2100 / 2600 - RM-937',
...
'Body' => ['Dimensions' =>...
}
Я сделал это до сих пор:
results = {}
tables = html.css('#specs-list table')
tables.each do |table|
category_key = table.css('th').text
results[category_key] = []
rows = table.css('tr')
rows.each do |row|
spec_key = row.css('.ttl').text
spec_content = row.css('.nfo').text
results[category_key] << {spec_key => spec_content}
end
end
Проблема в том, что, например, для сети 3G есть две строки, и я не уверен, как их получить под индексом 3G Network в моем хеше.
Это сложная для меня роль:
<tbody><tr>
<th rowspan="8" scope="row">General</th>
<td class="ttl"><a href="network-bands.php3">2G Network</a></td>
<td class="nfo">GSM 850 / 900 / 1800 / 1900 - all versions</td>
</tr><tr>
<td class="ttl"><a href="network-bands.php3">3G Network</a></td>
<td class="nfo">HSDPA 850 / 900 / 1900 / 2100 - RM-937, RM-939, RM-940</td>
</tr>
<tr>
<td class="ttl"> </td>
<td class="nfo">HSDPA 850 / 900 / 1700 / 1900 / 2100 - RM-938</td>
</tr>
</tbody>
Обратите внимание на строку <td class="ttl"> </td>
, она фактически не является новой категорией спецификации, а продолжением предыдущей. Таким образом, в идеале это будет идти в предыдущем.
Проблема в том, что в другой части HTML (при определении батареи основной категории) есть этот код:
<tbody><tr>
<th rowspan="4" scope="row">Battery</th>
<td class="ttl"> </td>
<td class="nfo">Non-removable Li-Ion 3400 mAh battery (BV-4BW)</td>
</tr><tr>
<td class="ttl"><a href="glossary.php3?term=stand-by-time">Stand-by</a></td>
<td class="nfo">Up to 768 h (2G) / Up to 768 h (3G)</td>
</tr><tr>
</tbody>
Как вы можете видеть, он начинается с пустого <td>
, и этот не следует переходить к предыдущему.
Я не уверен, как это решить.
Вам в основном нужно проверить, нет ли spec_key
. В этом случае вы должны добавить результаты к предыдущей spec_key
. Единственный улов в том, что вы должны следить за
charachter. Вот немного измененная версия вашего кода:
results = {}
tables = html.css('#specs-list table')
tables.each do |table|
category_key = table.css('th').text
rows = table.css('tr')
current_spec_key = nil
category_results = {}
rows.each do |row|
spec_key = row.css('.ttl').text.gsub("\u00a0",' ').strip #replace with space
spec_content = row.css('.nfo').text
if spec_key.empty?
category_results[current_spec_key] << ", #{spec_content}"
else
current_spec_key = spec_key
category_results[current_spec_key] = spec_content
end
end
results[category_key] = category_results
end
if spec_key.empty? && !current_spec_key.nil?
..."}, вы можете изменить первый, if
на if spec_key.empty? && !current_spec_key.nil?
, Если вам нужна специальная обработка первого раза, когда вы найдете пустой ключ, вы можете изменить первый, if
на if current_spec_key.nil? && spec_key.empty?
и затем добавьте elsif
и else
для двух других случаев.
spec_key
и, если он пуст, объединитьspec_content
с содержимым предыдущегоspec_key
.