Как изменить вывод словаря - PullRequest
3 голосов
/ 11 февраля 2020

Я перебираю новости на странице Scrapy, которая в основном представляет собой заголовок, метатекст и текстовое резюме. Код на самом деле работает нормально, но у меня проблема с выводом словаря. Выходные данные сначала отображают все заголовки, затем весь метатекст и, наконец, все текстовые сводки. Но то, что мне нужно, это одна новость за другой с заголовком, метатекстом и текстовым резюме. Я думаю, что-то не так с for l oop или селекторами?

Спасибо за любую помощь!

Мой код:

import scrapy
class testspider(scrapy.Spider):
    name = 'test'
    start_urls = ['https://oilprice.com/Latest-Energy-News/World-News']    

    def parse(self, response):
        all_news = response.xpath('//div[@class="tableGrid__column tableGrid__column--articleContent category"]')

        for singlenews in all_news:         
            title_item = singlenews.xpath('//div[@class="categoryArticle__content"]//a//text()').extract()
            meta_item = singlenews.xpath('//div[@class="categoryArticle__content"]//p[@class="categoryArticle__meta"]//text()').extract()
            extract_item = singlenews.xpath('//div[@class="categoryArticle__content"]//p[@class="categoryArticle__excerpt"]//text()').extract()      

            yield {
                'title_data' : title_item,
                'meta_data' :  meta_item,
                'extract_data' : extract_item        
            }

Выход:

{'title_data': ['Global Energy-Related CO2 Emissions Stopped Rising In 2019', 'BHP
 Is Now The World’s Top Copper Miner', 'U.S. Budget Proposal Includes Sale Of 15 
Mln Barrels Strategic Reserve Oil', ... , '**meta_data**': ['Feb 11, 2020 at 12:02
 | Tsvetana Paraskova', 'Feb 11, 2020 at 11:27 | MINING.com ', 'Feb 11, 2020 at 
09:59 | Irina Slav', ... , '**extract_data**': ['The world’s energy-related carbon
 dioxide (CO2) emissions remained flat in 2019, halting two years of emissions 
increases, as lower emissions in advanced economies offset growing emissions
 elsewhere, the International Energy…', 'BHP Group on Monday became the world’s 
largest copper miner based on production after Chile’s copper commission announced 
a slide in output at state-owned Codelco.\r\nHampered by declining grades 
Codelco…', 'The budget proposal President Trump released yesterday calls for the 
sale of 15 million barrels of oil from the Strategic Petroleum Reserve of the 
United States.\r\nThe proceeds from the…', ... , ']}

Ответы [ 2 ]

2 голосов
/ 11 февраля 2020

По вашему выводу кажется, что ваш код извлекает title, meta_data и extract_data одновременно и сохраняет его в одном словаре. Если вам нужен словарь для каждой новости на веб-сайте, который вы просматриваете, вы должны сначала получить все необходимые данные, а затем разбирать их в словарях по своему усмотрению. Таким образом, ваш код будет выглядеть примерно так

def parse(self, response):
    all_news = response.xpath('//div[@class="tableGrid__column tableGrid__column--articleContent category"]')  
    titles = all_news.xpath('//div[@class="categoryArticle__content"]//a//text()').extract()
    meta_items = all_news.xpath('//div[@class="categoryArticle__content"]//p[@class="categoryArticle__meta"]//text()').extract()
    extract_items = all_news.xpath('//div[@class="categoryArticle__content"]//p[@class="categoryArticle__excerpt"]//text()').extract()      

    # at this point titles, meta_items and extract_items should be 3 concurrent lists of the same length and now you can parse them as you need

    news_items = []
    for i in range(len(titles)): 
        news = { 'title': titles[i], 'meta_data': meta_items[i], 'extract_data': extract_items[i] }
        news_items.append(news)
    return news_items

Это должно возвращать новостные сообщения по вашему желанию.

0 голосов
/ 11 февраля 2020

Когда вы используете // в Xpath, поиск будет выполняться по всему документу, тогда строка

title_item = singlenews.xpath('//div[@class="categoryArticle__content"]//a//text()').extract()

вернет список со всем текстом в div, который соответствует этому фильтру div[@class="categoryArticle__content]

Что вам нужно сделать, это фильтр для относительного пути singlenews, попробуйте что-то вроде этого:

title_item = singlenews.xpath('./div[@class="categoryArticle__content"]//a//text()').extract()

Ref: https://devhints.io/xpath

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