Im currently working doing a webscrape which in my case if sydsvenskan but will be a template over time for other sites.
I have currently done:
from typing import Optional
import attr
import requests
from bs4 import BeautifulSoup
from loguru import logger
from requests import RequestException
from requests.exceptions import (
ConnectionError,
ConnectTimeout,
ProxyError,
ReadTimeout,
ChunkedEncodingError,
SSLError,
Timeout
)
@attr.dataclass
class Data:
store: str = attr.ib(factory=str)
name: Optional[str] = attr.ib(factory=str)
info: Optional[str] = attr.ib(factory=str)
image: Optional[str] = attr.ib(factory=str)
class Info:
def from_page(url: str) -> Data:
while True:
try:
with requests.get(url) as response:
if response.status_code == 404:
return Data(store="Sydsvenskan")
if response.ok:
doc = BeautifulSoup(response.text, 'html.parser')
else:
response.raise_for_status()
name = doc.select_one('span.prose-title')
info = doc.select_one('div.article__preamble-wrapper')
image = doc.select_one('img.article-image')
return Data(
store="Sydsvenskan",
name=name.text.strip() if name else '',
info=info.text.strip() if info else '',
image=image['src'] if image else '',
)
except (
ReadTimeout,
Timeout,
ConnectTimeout,
ConnectionError,
ChunkedEncodingError,
SSLError,
ProxyError
) as err:
logger.info(f"{type(err).__name__} at line {err.__traceback__.tb_lineno} of {__file__}: {err}")
continue
except RequestException as err:
logger.exception(f"{type(err).__name__} at line {err.__traceback__.tb_lineno} of {__file__},: {err}")
raise RequestException from err
except Exception as err:
logger.exception(f"{type(err).__name__} at line {err.__traceback__.tb_lineno} of {__file__},: {err}")
raise Exception from err
def main():
info = Info.from_page(
url="https://www.sydsvenskan.se/2021-07-14/flera-anhallna-for-senaste-tidens-skjutningar-i-malmo")
if info is None:
logger.info('No new payload')
else:
logger.info(f'New payload: {info}')
if __name__ == '__main__':
main()
The current "template" I have created is meant to be able to add more news sites in the future and to be able to use this as a template. We do know that each site is different so we will never have any similar but the template should make it easy to adept in the future.
I wonder if there is anything I can improve from here? I am mostly "worried" about the return of Data where I use the if else statement inside the dataclass, not sure if that is a correct way to do it?