Очистка вложенных данных и вставка их в один массив - PullRequest
0 голосов
/ 09 июня 2018

У меня есть следующая структура HTML:

<ul>
  <li>
    <div>
      <h3>TheFirst</h3>
    </div>
    <div class='LastDiv'>TheLast</div>
  </li>
  <li>
    <div>
      <h3>TheSecond</h3>
    </div>
    <div class='LastDiv'>TheLast</div>
  </li>
  <li>
    <div>
      <h3>TheNew</h3>
    </div>
    <div class='LastDiv'>TheLastNew</div>
  </li>
</ul>

Что я пытаюсь сделать здесь, это извлечь из этой структуры следующие данные:

{
  'TheLast': ['TheFirst', 'TheSecond'],
  'TheLastNew': ['TheNew']
}

Что я делаю, это следующее:

data = {}
list = response.css('ul li').extract()
for li in list:
    data[li.css('div.LastDiv::text')].append(li.css('div > h3::text'))
print(data)

Но я продолжаю получать эту ошибку:

AttributeError: у объекта 'str' нет атрибута 'css'

Есть ли более быстрый способизвлечь эти данные в таком наборе?

список значения =

['<li>\r\n    <div>\r\n      <h3>TheFirst</h3>\r\n    </div>\r\n    <div class="LastDiv">TheLast</div>\r\n  </li>', '<li>\r\n    <div>\r\n      <h3>TheSecond</h3>\r\n    </div>\r\n    <div class="LastDiv">TheLast</div>\r\n  </li>', '<li>\r\n    <div>\r\n      <h3>TheNew</h3>\r\n    </div>\r\n    <div class="LastDiv">TheLastNew</div>\r\n  </li>']

общий результат перед print() равен

>>> data = {}
>>> list = response.css('ul li').extract()
>>> for li in list:
...  data[li.css('div.LastDiv::text')].append(li.css('div > h3::text'))
...
Traceback (most recent call last):
  File "<console>", line 2, in <module>
AttributeError: 'str' object has no attribute 'css'

Ответы [ 2 ]

0 голосов
/ 09 июня 2018

Ответ Олега Т. неполный.data - это словарь, требующий, чтобы ключи реализовали __hash__, чего нет в SelectorList.Вот почему вы получили эту ошибку.

Правильное решение:

#!/usr/bin/env python3

import collections
from scrapy.selector import Selector

with open('input.html') as fd:
    content = fd.read()

response = Selector(text=content)

data = collections.defaultdict(list)
lst = response.css('ul li') #.extract()
for li in lst:
    key = li.css('div.LastDiv::text')[0].extract()
    data[key].append(li.css('div > h3::text')[0].extract())

print(dict(data))

, где input.html - это файл, содержащий фрагмент HTML в вашем вопросе.Это печатает то, что вы искали:

{'TheLast': ['TheFirst', 'TheSecond'], 'TheLastNew': ['TheNew']}
0 голосов
/ 09 июня 2018

Это произошло, потому что вы извлекаете html из 'ul li'.Затем вы попытались запустить 'html'.css ().Вы должны удалить ".extract ()", где вы предварительно подготовили переменную "list" для цикла.Как это:

from scrapy.selector import Selector

with open('input.html') as fd:
    content = fd.read()

response = Selector(text=content)

data = {}
list = response.css('ul li')
for li in list:
    key = li.css('div.LastDiv::text').extract_first()

    if key not in data:
        data[key] = []

    data[key].append(li.css('div > h3::text').extract_first())

print(data)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...