Я думаю, что это хорошая утилита для reduce
, так как после группировки вам нужно сначала избавиться от ID в результирующем [ID, VALUES]
массиве от group_by
и просто вернуть уменьшенную версию VALUES
части - все это можно сделать без каких-либо зависимостей ActiveSupport
и т. д.:
data
.group_by{ |d| d[:id] } # Get an array of [ID, [VALUES]]
.reduce([]) do |a, v| # Reduce it into a new empty array
# Append a new hash to the new array
a << {
id: v[1].first[:id], # Just take the ID of the first entry
foo: v[1].first[:foo], # Dito for foo
concatenated: v[1]
.sort_by{ |s| s[:sort] } # now sort all hashes by its sort key
.collect{ |s| s[:content] } # collect the content
.join # and merge it into a string
}
end
Выход:
[{:id=>14, :foo=>"2022", :concatenated=>"9105"},
{:id=>15, :foo=>"2888", :concatenated=>"3134"},
{:id=>16, :foo=>"3112", :concatenated=>"8449"}]
EDIT
У меня был другой подход в виду, когда я начал писать предыдущее решение, reduce
не было действительно необходимо, так как размер массива после group_by
не изменяется, поэтому достаточно map
.
Но пока переписывая код, я думал, что создание нового хэша со всеми ключами и копирование всех значений из первого хэша в VALUES
было слишком большим, поэтому было бы проще просто отказаться от служебных клавиш:
keys_to_ignore = [:sort, :content]
data
.group_by{ |d| d[:id] } # Get an array of [ID, [VALUES]]
.map do |v|
v[1]
.first # Take the first hash from [VALUES]
.merge({'concatenated': v[1] # Insert the concatenated values
.sort_by{ |s| s[:sort] } # now sort all hashes by its sort key
.collect{ |s| s[:content] } # collect the content
.join # and merge it into a string
})
.select { |k, _| !keys_to_ignore.include? k }
end
Выход
[{:id=>14, :foo=>"2022", :concatenated=>"9105"},
{:id=>15, :foo=>"2888", :concatenated=>"3134"},
{:id=>16, :foo=>"3112", :concatenated=>"8449"}]
Демо-версия здесь
Ну, вы меняете index
, но не используете его: ваш request_url
одинаков во время процесса. Если этот бит является тем, который вы ожидаете изменить страницу
yield scrapy.FormRequest(request_url,formdata=data,callback=self.parse_fb)
, то вы должны изменить request_url
перед вызовом этого.
Зачем вам BeautifulSoup? Все это лишнее. Вот рабочий код для вашего продукта:
import scrapy
class CodeInfo(scrapy.Item):
code = scrapy.Field()
class feedback_aliexpress_com(scrapy.Spider):
name = 'feedback_aliexpress_com'
domain = 'feedback.aliexpress.com'
allowed_domains = ['feedback.aliexpress.com']
start_urls = ['https://feedback.aliexpress.com/display/productEvaluation.htm?' +
'productId=32911361727&ownerMemberId=206054366&companyId=&memberType=seller&startValidDate=']
url = 'https://feedback.aliexpress.com/display/productEvaluation.htm'
page = 1
def parse(self, response):
code = CodeInfo()
if response.css('.user-country'):
for listing in response.css('.feedback-item'):
code['code'] = listing.css('.user-country > b::text').extract_first()
yield code
self.page += 1
self.url = 'https://feedback.aliexpress.com/display/productEvaluation.htm?productId=32911361727&ownerMemberId=206054366&page=' \
+ str(self.page)
yield response.follow(url=self.url, callback=self.parse)
Много лишнего))) Я знаю))) Проверьте это) сделал в спешке