2
\$\begingroup\$

Looking for a more efficient way of achieving this. In particular the combine_all_rss_lists so I don't need all those params. Feedparser module doesn't accept lists which is why I've had to initially break them into strings. Would be ideal to have minimal arguments as well.

def create_rss_urls():
    topics = ['business', 'technology', 'science_and_environment',
                      'politics', 'world', 'health',
                      'education', 'uk']
    url_list = []
    for topic in topics:
        url = f'http://feeds.bbci.co.uk/news/{topic}/rss.xml'
        url_list.append(url)
    return url_list    
    
def list_rss_feed(rss_feed_url):
    """Create a list of the top 10 articles for each RSS Feed topic.
    To be used by convert_rss_list_to_str() function."""

    data = feedparser.parse(rss_feed_url)
    i = 0
    full_feed_text_list = []
    while i < 10:  # Find first 10 articles
        feed_title_str = data['entries'][i]["title"]
        feed_description_str = data['entries'][i]['description']
    
        full_feed_text = feed_title_str + ' ' + feed_description_str
        i = i + 1  # Move to the next article
        full_feed_text_list.append(full_feed_text)  # Add each article to this list
        return full_feed_text_list        
    
def combine_all_rss_lists(rss_list: list, rss_list_2: list, rss_list_3: list, rss_list_4: list, rss_list_5: list, rss_list_6: list, rss_list_7: list, rss_list_8: list):
            full_list = rss_list + rss_list_2 + rss_list_3 + rss_list_4 + rss_list_5 + rss_list_6 + rss_list_7 + rss_list_8
    return full_list        
    
def convert_rss_list_to_str(rss_list: list):
    """Convert RSS feed text to string which is to be displayed in rss_live_feeds."""
    
    s = '\n\n'.join(str(x) for x in rss_list)
    return s

topic_urls = create_rss_urls()
bbc_rss_business = list_rss_feed(topic_urls[0])
bbc_rss_technology = list_rss_feed(topic_urls[1])
bbc_science_and_environment_feed = list_rss_feed(topic_urls[2])
bbc_politics_feed = list_rss_feed(topic_urls[3])
bbc_world_feed = list_rss_feed(topic_urls[4])
bbc_health_feed = list_rss_feed(topic_urls[5])
bbc_uk_feed = list_rss_feed(topic_urls[6])
bbc_education_feed = list_rss_feed(topic_urls[7])
# investing_feed = list_rss_feed(topic_urls[8]) # Add to full_list later
    
full_list = combine_all_rss_lists(bbc_rss_business, bbc_rss_technology, bbc_science_and_environment_feed,
            bbc_politics_feed, bbc_world_feed, bbc_health_feed, bbc_uk_feed, bbc_education_feed)

print(str(convert_rss_list_to_str(full_list)))
\$\endgroup\$
1
  • \$\begingroup\$ Please show all of your imports, including feedparser \$\endgroup\$
    – Reinderien
    Sep 23 at 21:11

1 Answer 1

2
\$\begingroup\$

Your topics should be a tuple and not a list, and if you want they can be moved to a global constant.

Add PEP484 type hints.

I don't think that feedparser is able to process feeds incrementally. If you truly do want to pull only the first ten items from each topic, and only pay the bandwidth and processing costs for them and ignore the rest, you have to cut to a lower level of abstraction (probably Requests and sax).

Don't hard-code indices [0], [1] etc. Computers are good at loops.

Suggested

from contextlib import contextmanager
from itertools import islice
from typing import Iterator, Iterable, NamedTuple, Optional
from xml.sax import make_parser
from xml.sax.handler import ContentHandler
from xml.sax.xmlreader import AttributesImpl

from requests import Session


TOPICS = ('business', 'technology', 'science_and_environment',
          'politics', 'world', 'health', 'education', 'uk')


@contextmanager
def load_feed(session: Session, topic: str) -> Iterator[Iterable[str]]:
    with session.get(
        url=f'http://feeds.bbci.co.uk/news/{topic}/rss.xml',
        headers={
            'Accept': 'application/rss+xml',
            'Accept-Encoding': 'gzip',
        },
        stream=True,
    ) as resp:
        resp.raise_for_status()
        yield resp.iter_content(chunk_size=1024, decode_unicode=True)


class Item(NamedTuple):
    title: str
    desc: str

    def __str__(self) -> str:
        return f'{self.title}: {self.desc}'


class FeedHandler(ContentHandler):
    def __init__(self) -> None:
        super().__init__()
        self.collecting_cdata = False
        self.items: list[Item] = []
        self.title: Optional[str] = None
        self.desc: Optional[str] = None
        self.text = ''

    def startElement(self, name: str, attrs: AttributesImpl) -> None:
        match name:
            case 'item':
                self.title = None
                self.desc = None
            case 'title' | 'description':
                self.text = ''
                self.collecting_cdata = True
            case _:
                self.collecting_cdata = False

    def characters(self, content: str) -> None:
        if self.collecting_cdata:
            self.text += content

    def endElement(self, name: str) -> None:
        match name:
            case 'title':
                self.title = self.text
            case 'description':
                self.desc = self.text
            case 'item':
                self.items.append(Item(self.title, self.desc))
        self.collecting_cdata = False

    def output(self) -> list[Item]:
        to_output = self.items
        self.items = []
        return to_output


def parse_feed(chunks: Iterable[bytes]) -> Iterator[Item]:
    handler = FeedHandler()
    parser = make_parser(('xml.sax.expatreader',))
    parser.setContentHandler(handler)

    for chunk in chunks:
        parser.feed(chunk)
        yield from handler.output()


def main() -> None:
    with Session() as session:
        for topic in TOPICS:
            print(topic)
            with load_feed(session, topic) as chunks:
                for element in islice(parse_feed(chunks), 10):
                    print(element)
            print()


if __name__ == '__main__':
    main()

Output

business
Pound sinks as investors question huge tax cuts: Markets worry over the outlook for government finances following the biggest tax cutting moves in 50 years.
Mini-budget: What it means for you and your finances: Chancellor Kwasi Kwarteng has delivered what the government calls a "fiscal event". Here is how it affects you.
'We'll be lucky to keep our heads above water': The BBC talked to households and businesses to get their reactions to the mini-budget.
Goldman Sachs: Sexual assault claims revealed in pay bias suit: Goldman Sachs is accused of "boys' club" culture that discriminated against women.
Income tax to be cut by 1p from April: The basic rate of income tax will fall by 1p from April with most people paying 19p instead of 20p for each pound.
Stamp duty cut in bid to help house buyers: The chancellor says the changes mean 200,000 more house buyers will no longer pay the tax.
At a glance: What's in the mini-budget?: Chancellor Kwasi Kwarteng outlines changes to tax, stamp duty and rules for those claiming benefits.
Universal credit rules tightened for part-time workers: The chancellor announced part-time workers will see their benefits cut if they don't try to earn more.
UK may already be in recession - Bank of England: The warning comes as the Bank raises interest rates to 2.25% - the highest level for 14 years.
Real Living Wage rises by record 10% to £10.90 an hour: A record increase in the voluntary pay scheme will benefit 400,000 workers.

technology
Testing the new iPhone: From battery to always-on screen: The BBC's Technology Editor, Zoe Kleinman, has been testing out the latest Apple smartphone.
Tesla ordered to recall more than a million US cars: The US car-safety watchdog says a window glitch is affecting all four Tesla models.
Iran unrest: What's going on with Iran and the internet?: The internet is cutting out and residents are unable to access social media in parts of the country.
Rape posts every half-hour found on online incel forum: More must be done to tackle women-hating movement incel, the Centre for Countering Digital Hate warns.
Warning over scam energy bill support messages: Emails and texts link to a fake Ofgem website where people's personal details are demanded.
Oxfordshire teen arrested in police hacking investigation: The National Cyber Crime Unit detained a 17-year-old from Oxfordshire on Thursday evening.
Australia phones cyber-attack exposes personal data: Optus is looking into the unauthorised access of data including names, addresses and passport numbers.
Twitch announces slots and roulette gambling ban: The livestreaming site will prohibit streams of slots, roulette or dice games from many jurisdictions.
Molly Russell inquest: Instagram clips seen by teen 'most distressing': The 14-year-old girl viewed material about self-harm and suicide before she died in 2017.
Online Safety Bill to return as soon as possible: But rules to tackle "legal but harmful" material will change over free-speech fears, a minister says.

science_and_environment
Would more UK gas actually bring down prices?: The government is committed to extracting more oil and gas in the North Sea.
Climate change risk to coastal castles - English Heritage: Rising sea levels are threatening ancient castles and forts at an accelerating rate, says English Heritage.
Climate change: Spike in Amazon emissions linked to law enforcement: Scientists say a huge increase in deforestation in the Amazon is linked to lax law enforcement.
Fracking ban lifted, government announces: Scientific review into fracking concludes there is still a limited understanding of impacts.
Rural areas hit harder by cost-of-living crisis, study finds: People living in the countryside face higher costs than those in urban areas, a new report finds.
Artemis: Nasa's Moon rocket completes fuelling test: The Space Launch System edges closer to a maiden flight after concluding a tanking demonstration.
School uniforms in N America linked to PFAS "forever chemicals": A study of school uniforms in the US and Canada shows high levels of chemical substances linked to health issues.
Ringed Neptune captured by James Webb telescope: The super space observatory returns spectacular imagery of the Solar System's most distant planet.
Prince William 'comforted' by support for his environmental work: He praised the passion of people supporting the Earthshot environmental prize he helped set up.
HS2 wins route-length High Court injunction: A judge grants an 'extensive' injunction in order to prevent access without permission to HS2 land or disruption taking place to its construction.

politics
Kwasi Kwarteng defends massive tax cuts as fair for all: The chancellor has faced criticism for cutting taxes for the wealthy during a cost-of-living crisis.
Jeremy Corbyn: Tory economic plan is irresponsible: The former Labour leader says his borrowing would have been for investment not "to pay bankers' bonuses".
Now is the time for Starmer to be bold, says union leader: Unite's general secretary predicts senior Labour MPs will soon return to picket lines.
Income tax to be cut by 1p from April: The basic rate of income tax will fall by 1p from April with most people paying 19p instead of 20p for each pound.
Stamp duty cut in bid to help house buyers: The chancellor says the changes mean 200,000 more house buyers will no longer pay the tax.
A not-so-mini-budget: What’s it all about?: The BBC’s Nick Eardley sets out the key headlines from the chancellor’s massive shake-up of the UK’s finances.
At a glance: What's in the mini-budget?: Chancellor Kwasi Kwarteng outlines changes to tax, stamp duty and rules for those claiming benefits.
Kwasi Kwarteng's mini-budget of tax cuts reward the wealthy, Labour says: Shadow Chancellor Rachel Reeves says the mini-budget is "admission of 12 years of economic failure".
Palestinian anger at possible UK Jerusalem embassy move: It comes after the UK PM is said to have told Israel's leader she might relocate it to Jerusalem.
Chancellor Kwasi Kwarteng hails 'new era' as he unveils tax cuts: The chancellor announces the biggest tax cuts since 1972 in a significant change of policy.

world
Ukraine 'referendums': Soldiers go door-to-door for votes in polls: Russia is holding the self-styled referendums in parts of Ukraine it wants to claim control over.
Ukraine war: Russia reveals exemptions as men flee call-up: IT workers, bankers and state media reporters will avoid Russia's first draft since World War Two.
Iran protests: US to ease internet curbs for Iranians: The move comes after Iran tries to clamp down on internet freedom to stamp out widespread protests.
Iran unrest: What's going on with Iran and the internet?: The internet is cutting out and residents are unable to access social media in parts of the country.
Magnus Carlsen and Hans Niemann: The cheating row that's blowing up the chess world: Magnus Carlsen's apparent accusation against Hans Niemann is the biggest chess scandal in years.
Italian election campaign ends as far right bids for power: Political leaders hold rallies ahead of elections on Sunday that could bring Giorgia Meloni to power.
Donors spending millions on Trump's legal battles: The former president's mounting bills are being paid by donors and the Republican party.
Goldman Sachs: Sexual assault claims revealed in pay bias suit: Goldman Sachs is accused of "boys' club" culture that discriminated against women.
Palestinian anger at possible UK Jerusalem embassy move: It comes after the UK PM is said to have told Israel's leader she might relocate it to Jerusalem.
South Korean President Yoon Suk-yeol denies US insult caught on hot mic: Yoon Suk-yeol denies insulting the US Congress after remarks he made were caught on an open mic.

health
Covid: First rise in infections in UK since July: The largest rise was in secondary school children as the new term started, according to the ONS.
Cancer-killing virus shows promise in patients: One man injected with the modified cold sore virus saw his tumour completely disappear.
£500m funding to help hospitals discharge patients: The money is part of a package of measures to support NHS and care system this winter, ministers say.
Can the NHS learn from Germany’s health system?: Despite public support for the NHS, satisfaction levels have fallen, raising thoughts of reform.
Pret a Manger customer had fatal reaction to 'vegan' wrap: Celia Marsh had a severe dairy allergy and ate food labelled as vegan that had traces of milk in it.
Many English maternity units not meeting safety standards: More than half of England's maternity units require improvements in safety, BBC analysis finds.
BT Group: Hundreds of 999 call handlers to join strikes: Emergency call centre staff will join 40,000 BT workers walking out in October, their union says.
NHS waiting list in Wales: Patients turn to surgery abroad: As the waiting list reaches a record 743,000, patients are self-funding treatment in Lithuania.
Scotland's A&E waiting times worst on record: Weekly figures show that a record number of A&E patients waited more than four hours.
Covid: Oxford oncologist in plea to government over Evusheld: Dr Lennard Lee wants the government to reconsider rolling out Evusheld for people who are immunosuppressed.

education
Five things to take to university - and one to avoid: Brighten up your accommodation, make friends and save on costs with these handy items.
Study finds Cambridge University 'benefited from slavery': A report commissioned by vice-chancellor, Prof Stephen Toope, prompts a raft of recommendations.
Cost of living: Students struggling with impact of soaring prices: One student tells the BBC of the isolating effect of running out of cash while studying at university.
Free nursery childcare needed as costs rocket, says TUC: Trade union chief Frances O'Grady says soaring nursery fees are causing parents huge stress.
Molly Russell's inquest to put focus on big tech: The teenager's inquest begins today and some see it as test of the power of US tech giants.
Scotland's largest teachers' union backs strike: EIS members have rejected a 5% pay offer made by local authorities and supported industrial action.
School energy support is not enough to solve crisis, Essex head warns: Vic Goddard, the head of four schools in Harlow, Essex, is struggling to sleep due to the situation.
Bus catches fire on way to Swavesey Village College: The fire service says "thanks to the fast actions of the driver, the bus was evacuated quickly".
Gordonstoun: The Scottish school that educated a king: The decision for the future King Charles to be educated at Gordonstoun was a departure from the royal norm.
King Charles III: 'Without Prince's Trust I'd be in prison or dead': The new king set up the charity in 1976 to help young people get jobs, education and training.

uk
Kwasi Kwarteng defends massive tax cuts as fair for all: The chancellor has faced criticism for cutting taxes for the wealthy during a cost-of-living crisis.
Jeremy Corbyn: Tory economic plan is irresponsible: The former Labour leader says his borrowing would have been for investment not "to pay bankers' bonuses".
Now is the time for Starmer to be bold, says union leader: Unite's general secretary predicts senior Labour MPs will soon return to picket lines.
EuroMillions result: UK ticket-holder wins £171m jackpot: If they are a single player, the win would make them richer than Adele or Ozzy Osbourne.
King Charles III's less formal photo as working monarch: He appears in an unconventional official photo which shows him carrying out his head of state duties.
Italy 1-0 England: Gareth Southgate's side relegated after Nations League defeat: England are relegated to the Nations League second tier for the first time following defeat by Italy in Milan.
Tearful Federer ends career with final match in London: Roger Federer brings the curtain down on his illustrious career by teaming up with fellow great Rafael Nadal on an emotional night in London.
Home Secretary Suella Braverman tells police to stop symbolic gestures: The new home secretary writes to police chiefs saying trust has been shattered and calling for change.
Laver Cup: Protester sets arm on fire after entering the court: A protester set his arm on fire after running on court and briefly stopping play during the Laver Cup at the O2 Arena in London.
Petrol: Supermarkets no longer selling cheapest fuel, RAC says: Some are driving miles searching for cheaper fuel, as research claims small garages are cheaper.
\$\endgroup\$
1
  • \$\begingroup\$ Now I have replaced the previous code with your solution, the PyQt5 GUI textarea no longer appears. How would it implement the new code within a PyQt5 textarea. The current way is: class Ui_MainWindow(object): ... def setupUi(self, MainWindow): self.rss_live_feeds = QtWidgets.QTextBrowser(self.centralwidget) self.rss_live_feeds.setGeometry(QtCore.QRect(10, 110, 881, 121)) self.rss_live_feeds.setObjectName("rss_live_feeds") self.rss_live_feeds.setText(str(convert_rss_list_to_str(full_list))) \$\endgroup\$
    – Luca
    Sep 24 at 12:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.