#python #dictionary #web-scraping
#python #словарь #очистка веб-страниц
Вопрос:
Это моя первая попытка создать что-то не веб-и включающее логическое кодирование.
Пожалуйста, взгляните на этот ужасный словарь ниже:
Messy_Dict=
{
'name': "['\r\n NASDAQ: BKEP\r\n ']",
'underlying': "['1.12']",
'strike_prices_list': ["['2.50'", " '5.00'", " '7.50']"],
'call_bid': ["['\r\n0.05 '", " '\r\n0.00 '", " '\r\n0.00 ']"],
'put_ask': ["['\r\n2.10 '", " '\r\n4.50 '", " '\r\n7.00 ']"]
}
Что я хочу сделать, так это очистить ненужные подстроки внутри каждого значения словаря, чтобы получить что-то вроде этого:
Clean_Dict=
{
'name': "BKEP",
'underlying': "1.12",
'strike_prices_list': ["2.50", "5.00", "7.50"],
'call_bid': ["0.05", "0.00", "0.00"],
'put_ask': ["2.10", "4.50", "7.00"]
}
Мне удалось перейти от Messy_Dict к Clean_Dict, но я использовал для этого очень варварские средства. Я просто скажу, что он включал цикл for и несколько методов strip(), replace(«, «). И мне больно смотреть на этот блок кода в моем файле .py.
Итак, я думаю, есть ли более элегантный метод для выполнения желаемой задачи преобразования Messy_Dict в Clean_Dict? Я чувствую, что мне чего-то не хватает в моих основах.
Редактировать
def parse(self, response):
strike_prices_main = response.css('.highlight , .aright .strike-col').css('::text').extract()
if not strike_prices_main:
pass
else:
name = response.css('#instrumentticker::text').extract()
strike_prices_list = response.css('.aright .strike-col').css('::text').extract()
call_bid = response.css('.aright td:nth-child(5)').css('::text').extract()
put_ask = response.css('.aright td:nth-child(14)').css('::text').extract()
underlying = response.css('.pricewrap .bgLast').css('::text').extract()
file.write('%s|%s|%s|%s|%sn'%(name,underlying,strike_prices_list,call_bid,put_ask))
Используя пауков для обхода!
Комментарии:
1. вы пробовали повторять ключи и для каждого значения использовать регулярное выражение, чтобы заменить все недопустимые символы?
2. правильный вопрос в этом случае заключается в том, откуда берется «беспорядочный» dict. Это очень похоже на JSON, который каким-то образом подвергся злоупотреблениям, чтобы стать таким… Возможно, ответ json, который не был обработан должным образом?
3. Сколько циклов for и операторов регулярных выражений это заняло бы?
4. @buran я очищал Yahoo Finance, чтобы получить некоторые данные! И, черт возьми, это было напечатано в моем cmd prmt, хахаха, ой
5. @LowaiisTan, Итак, мое предположение верно, и лучшим подходом было бы показать ваш код, который запрашивает Yahoo finance, и получить помощь с ним. В нынешнем виде это проблема XY. Вы можете получить идеально отформатированный действительный ответ в формате JSON от yahoo finance
Ответ №1:
Может быть, вот так:
import re
Messy_Dict=
{
'name': "['\r\n NASDAQ: BKEP\r\n ']",
'underlying': "['1.12']",
'strike_prices_list': ["['2.50'", " '5.00'", " '7.50']"],
'call_bid': ["['\r\n0.05 '", " '\r\n0.00 '", " '\r\n0.00 ']"],
'put_ask': ["['\r\n2.10 '", " '\r\n4.50 '", " '\r\n7.00 ']"]
}
regexstr = "\\(r|n)|s|[|]|'|NASDAQ:"
dict_clean = {}
for k, v in Messy_Dict.items():
if isinstance(v, list):
list_clean = []
for el in v:
el_clean = re.sub(regexstr, "", el)
list_clean.append(el_clean)
dict_clean[k] = list_clean
else:
dict_clean[k] = re.sub(regexstr, "", v)
dict_clean
Ответ №2:
Вы можете использовать регулярные выражения.
Пример:
import re
messy_dict = {
'name': "['\r\n NASDAQ: BKEP\r\n ']",
'underlying': "['1.12']",
'strike_prices_list': ["['2.50'", " '5.00'", " '7.50']"],
'call_bid': ["['\r\n0.05 '", " '\r\n0.00 '", " '\r\n0.00 ']"],
'put_ask': ["['\r\n2.10 '", " '\r\n4.50 '", " '\r\n7.00 ']"]
}
for key in messy_dict:
stripfunc = lambda x: re.sub('[^d.]', '', str(x))
if type(messy_dict[key]) is list:
messy_dict[key] = [stripfunc(x) for x in messy_dict[key]]
else:
messy_dict[key] = stripfunc(messy_dict[key])
print(messy_dict)
Объяснение: [^ ] соответствует всему, чего нет в наборе. d предназначен для числовых значений, а обратная косая черта скрывает точку. Используя str (val) для создания строк из списков.
Вывод: {'name': '', 'underlying': '1.12', 'strike_prices_list': ['2.50', '5.00', '7.50'], 'call_bid': ['0.05', '0.00', '0.00'], 'put_ask': ['2.10', '4.50', '7.00']}
Редактировать: только что заметил, что вы также хотите сохранить точку. Обновил код.
Комментарии:
1. Упс, я этого не делал. Исправлено.
2. Предпочел бы немного большую точность в обмен на меньшую краткость!
3. Ага, это генерирует результат, о котором вы просили?