Search code examples
python-3.xbeautifulsouphtml-parsing

How can I extract only certain parts of the body of an article?


In my text_scraper(page_soup), I realized that towards the end I get irrelevant information that does not relate to my article at all. What's a general approach that would get rid of the irrelevant information?

from urllib.request import urlopen as uReq
from bs4 import BeautifulSoup as soup
import re


# Initializing our dictionary
dictionary = {}

# Initializing our url key
url_key = 'url'
dictionary.setdefault(url_key, [])

# Initializing our text key
text_key = 'text'
dictionary.setdefault(text_key, [])

def text_scraper(page_soup):
    text_body = ''
    # Returns the text of p tags, we stopped it at -5 bc that's when the text is irrelevant to the article
    for p in page_soup.find_all('p'):
        text_body += p.text
    return(text_body)

def article_scraper(url):
    # Opening up the connection, grabbing the page
    uClient = uReq(url)
    page_html = uClient.read()
    uClient.close()

    # HTML parsing
    page_soup = soup(page_html, "html.parser")

    dictionary['url'].append(url)
    dictionary['text'] = text_scraper(page_soup)
    return dictionary

articles_zero = 'https://www.sfchronicle.com/news/bayarea/heatherknight/article/Special-education-teacher-a-prime-example-of-13560483.php'
article = article_scraper(articles_zero)
article

Solution

  • If you want only the text related to the article, you can just adapt your pointer in your text_scraper method and scrape only the <p> tags in the <section>:

    def text_scraper(page_soup):
        text_body = ''
        # Find only the text related to the article:
        article_section = page_soup.find('section',{'class':'body'})
        # Returns the text of p tags, we stopped it at -5 bc that's when the text is irrelevant to the article
        for p in article_section.find_all('p'):
            if p.previousSibling and p.previousSibling.name is not 'em':
                text_body += p.text
        return(text_body)
    

    Then the article will be returned without the text inside the footer (Heather Knight is a columnist [...] and their struggles.)

    EDIT: Added test on parent to avoid the last part San Francisco Chronicle[...]Twitter: @hknightsf