Использование scrapy для извлечения и структурирования данных таблицы

Я новичок в python и scrapy и подумал, что попробую простой сайт с обзорами, чтобы очистить. Хотя большая часть структуры сайта проста, у меня возникают проблемы с извлечением содержания отзывов. Эта часть визуально разбита на группы по 3 (текст справа от полей 良 (хорошо), 悪 (плохо), 感 (показы)), но у меня возникают проблемы с извлечением этого контента и его привязкой к рецензенту или раздел обзора из-за использования общих div,
, / n и другого форматирования.

Любая помощь будет оценена.

Вот сайт и код, который я пробовал для их захвата, с некоторыми результатами. http://www.psmk2.net/ps2/soft_06/rpg/p3_log1.html

(1):

response.xpath('//tr//td[@valign="top"]//text()').getall()

Это возвращает весь набор обзоров, но содержит разметку новой строки и, что более важно, отображает каждую строку как отдельную запись. Из-за этого я не могу понять, где заканчиваются хорошие, плохие и впечатляющие части, а также не могу легко проанализировать каждый отдельный отзыв, поскольку длина записи меняется.

['\ n 弱点 を つ い 時 の メ 、 つ か れ た と メ ッ ト は っ き て て 良 い', '\ n コ \ , '\ n 難易 度 は や し め な の び や す い', '\ n タ ル タ ロ ス し か ジ ョ 無 く て 飽 る'........ и т. д.

(2) В качестве альтернативы я попробовал:

response.xpath('//tr//td[@valign="top"]')[0].get()

Что на самом деле близко к тому, что я хотел бы, за исключением разметки. Вот вроде как возвращает все поле раздела обзора. Каждый третий элемент должен отражать достоинства каждого отдельного обзора (я заменил ‹› на (), чтобы показать необработанный результат).

(td valign = top) \ n 精 一杯 考 え し た (br) \ n (br) \ n 戦 闘 が 白 い で す ね
\ n 主人公 だ け が ・ ・ ・ (br) \ n 従 来 の プ レ タ ー バ ト ル の 進化 な で (br) \ n (br) \ n 以上 で す (/ td)

(3) Решив, что смогу получить только текст, я попробовал:

response.xpath('//tr//td[@valign="top"]//text()')[0].get()

Но это предоставляет только каждую строку за раз, с \ n впереди. Как и в случае с (1), построчное отображение затрудняет приписывание рецензий рецензентам и соответствующему разделу в их рецензии.

Из них (2) кажется наиболее близким к тому, что я хочу, и я надеялся, что смогу получить какое-то направление в том, как получить каждый раздел для каждого обзора без разметки. Я подумал, что, поскольку эти разделы входят в наборы по 3, их можно было бы поместить в список, который упростил бы их извлечение в будущем (т.е. все хорошие отзывы следуют 0, 0 + 3; все плохие 1, 1 + 3 ... и т. д.) ... но сначала мне нужно получить элементы.

Я думал и пробовал повторять каждую строку с условием if (что-то вроде :)

i = 0
if i <= len(response.xpath('//tr//td[@valign="top"]//text()').getall()):
    yield {response.xpath('//tr//td[@valign="top"]')[i].get()}
    i + 1

чтобы вытащить их, но я немного не понимаю, как реализовать что-то вроде этого. Не уверен, куда он должен идти. Я кратко посмотрел на Item Loader, но, поскольку я новичок в этом, я все еще пытаюсь понять это.

Вот блок, где находится код обзора.

    def parse(self, response):
    for table in response.xpath('body'):
        yield {
            #code for other elements in review
            'date': response.xpath('//td//div[@align="left"]//text()').getall(),
            'name': response.xpath('//td//div[@align="right"]//text()').getall(),

            #this includes the above elements, and is regualr enough I can systematically extract what I want
            'categories': response.xpath('//tr//td[@class="koumoku"]//text()').getall(),
            'scores': response.xpath('//tr//td[@class="tokuten_k"]//text()').getall(),
            'play_time': response.xpath('//td[@align="right"]//span[@id="setumei"]//text()').getall(),
            #reviews code here

        }

person simishu    schedule 31.08.2020    source источник


Ответы (1)


Довольно простая задача с использованием части текста в качестве привязки (я использовал string, чтобы получить текстовое содержимое для всего td):

for review_node in response.xpath('//table[@width="645"]'):
    good = review_node.xpath('string(.//td[b[starts-with(., "良")]]/following-sibling::td[1])').get()
    bad= review_node.xpath('string(.//td[b[starts-with(., "悪")]]/following-sibling::td[1])').get()
...............
person gangabass    schedule 01.09.2020
comment
Это сработало! Первоначально казалось, что он возвращает последний обзор на странице, но я настроил xpath, чтобы получить первый. - person simishu; 01.09.2020