Двойная попытка / исключение - лучшие практики bs4 - PullRequest
0 голосов
/ 19 января 2020

Ниже вы можете найти один из методов, которые я использую, чтобы получить некоторые детали из списка вакансий в SO. Я не знаю заранее, будут ли на странице все необходимые поля (отсюда и пустое объявление dict вверху).

Теперь, единственный случай, когда я хочу, чтобы метод генерировал ошибку, - это случай HTTPError, если в нем не найдено ни одного поля, я бы хотел просто вернуть пустой dict. Использование 2 разных try/except блоков (по одному для каждого типа ошибки) приводит к правильному поведению, но мне интересно, есть ли более элегантный / лаконичный способ добиться этого.

get_so_extras.py :

from bs4 import BeautifulSoup
import re
imoprt requests

ua = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'
}


def get_so_extras(job_url):
    """
    Get additional information from stackoverflow.com job listing page.
    Args:
        job_url (str): url pointing at job listing's page
    Returns:
        dict: a dict containing additional info about the job
        listing and company.
    """

    extra_info = {
        "company_logo": None,
        "salary_lower": None,
        "salary_upper": None,
        "salary_currency": None
    }

    try:
        page = requests.get(job_url, headers=ua)
        soup = BeautifulSoup(page.text, "html.parser")

    except requests.HTTPError as e:
        print(e)

    try:
        logo = soup.find(
            "div", attrs={"class": "grid--cell bg-white fl-shrink0"}).img["src"]
        extra_info["company_logo"] = logo

        # Salary information
        salary = soup.find("div", attrs={'class': 'mt12'}).span["title"]
        extra_info["salary_currency"] = re.match("[^\d\.\,\s]+", salary)[0]
        extra_info["salary_lower"] = re.findall("(\d+)(|\s-\s)", salary)[0][0]
        extra_info["salary_upper"] = re.findall("(\d+)(|\s-\s)", salary)[1][0]

    except Exception as e:
        pass

    time.sleep(3)  # be kind
    return extra_info

Спасибо за любые отзывы

1 Ответ

1 голос
/ 20 января 2020

Вы можете поймать нужную ошибку, используя только одну попытку, и несколько, кроме.

Для своего фрагмента вы можете сделать что-то вроде этого:

try:
    page = requests.get(job_url, headers=ua)
    soup = BeautifulSoup(page.text, "html.parser")
    logo = soup.find(
        "div", attrs={"class": "grid--cell bg-white fl-shrink0"}).img["src"]
    extra_info["company_logo"] = logo

    # Salary information
    salary = soup.find("div", attrs={'class': 'mt12'}).span["title"]
    extra_info["salary_currency"] = re.match("[^\d\.\,\s]+", salary)[0]
    extra_info["salary_lower"] = re.findall("(\d+)(|\s-\s)", salary)[0][0]
    extra_info["salary_upper"] = re.findall("(\d+)(|\s-\s)", salary)[1][0]

except requests.HTTPError as e:
    print(e)
except Exception as e:
    pass
...