Использование FOR l oop и IF для BeautifulSoup в Python - PullRequest
0 голосов
/ 27 мая 2020

Я пытаюсь вытащить мета-описание нескольких веб-страниц. Ниже мой код:

URL_List = ['https://digisapient.com', 'https://dataquest.io']
Meta_Description = []

for url in URL_List:
    response = requests.get(url, headers=headers)
    #lower_response_text = response.text.lower()
    soup = BeautifulSoup(response.text, 'lxml')
    metas = soup.find_all('meta')
    for m in metas:
        if m.get ('name') == 'description':
            desc = m.get('content')
            Meta_Description.append(desc)
        else:
            desc = "Not Found"
            Meta_Description.append(desc)

Теперь это возвращает мне следующее:

['Not Found',
 'Not Found',
 'Not Found',
 'Not Found',
 'Learn Python, R, and SQL skills. Follow career paths to become a job-qualified data scientist, analyst, or engineer with interactive data science courses!',
 'Not Found',
 'Not Found',
 'Not Found',
 'Not Found']

Я хочу вытащить content, где мета name == 'description'. В случае, если условие не совпадает, т. Е. Страница не имеет метасвойства с name == 'description, она должна возвращать Not Found.

Ожидаемый результат:

['Not Found',
 'Learn Python, R, and SQL skills. Follow career paths to become a job-qualified data scientist, analyst, or engineer with interactive data science courses!']

Пожалуйста предложить.

Ответы [ 2 ]

0 голосов
/ 27 мая 2020

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

Ваш текущий код

Давайте посмотрим.

for url in URL_List:

Для каждой страницы в вашем списке

    metas = soup.find_all('meta')

вы хотите все теги <meta> (независимо от других атрибутов).

    for m in metas:

Для каждого тега <meta> проверьте, является ли он <meta name="description">. Если это так, сохраните его content; в противном случае сохраните "Not Found".

HTML <meta>

См. дополнительную информацию в документах MDN . Короче говоря, вы можете использовать <meta> для большего количества мета потребностей, и поэтому вы можете иметь несколько тегов <meta> в своем HTML документе.

Ваши URL

Если вы действительно откроете свои URL-адреса и посмотрите на HTML, вы увидите, что получите

digisapient (1 <meta>)

        <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />

dataquest (намного больше <meta> s)

    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="Learn Python, R, and SQL skills. Follow career paths to become a job-qualified data scientist, analyst, or engineer with interactive data science courses!" />
    <meta name="robots" content="index, follow" />
    <meta name="googlebot" content="index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1" />
    <meta name="bingbot" content="index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1" />
    <meta property="og:locale" content="en_US" />
    <meta property="og:type" content="website" />
    <meta property="og:title" content="Learn Data Science Online and Build Data Skills with Dataquest" />
    <meta property="og:description" content="Learn Python, R, and SQL skills. Follow career paths to become a job-qualified data scientist, analyst, or engineer with interactive data science courses!" />
    <meta property="og:url" content="https://www.dataquest.io/" />
    <meta property="og:site_name" content="Dataquest" />
    <meta property="article:publisher" content="https://www.facebook.com/dataquestio" />
    <meta property="article:modified_time" content="2020-05-14T22:43:29+00:00" />
    <meta property="og:image" content="https://www.dataquest.io/wp-content/uploads/2015/02/dataquest-learn-data-science-logo.jpg" />
    <meta property="og:image:width" content="1040" />
    <meta property="og:image:height" content="520" />
    <meta name="twitter:card" content="summary_large_image" />
    <meta name="twitter:creator" content="@dataquestio" />
    <meta name="twitter:site" content="@dataquestio" />

Как видите, второй веб-сайт имеет гораздо больше таких тегов в своем содержании, и для каждого из них вы go через последний if/else выписка; если у него нет name="description", вы сохраняете "Not Found" в своем наборе результатов.

Фактические результаты

Чтобы проверить, что ваша программа делает за раз, и лучше понимать различные значения, которые переменные получают с течением времени, я думаю, что стоит поискать отладку и начать ее делать. , например, Downloaded URL http://..., Found 4 <meta> tags, Found 0 <meta name="description".

Я предлагаю вам go по вашей программе построчно, с HTML с другой стороны, и попробуйте посмотреть, что должно произойти. .

Как добраться

Судя по вашим ожидаемым результатам, вам кажется, что на самом деле вам наплевать на "Not Found" s, и вы заранее знаете, что вам всегда нужны теги <meta name="description"> .

С CSS Селекторами

Вы можете попробовать выбрать элементы DOM самостоятельно в браузере, используя document.querySelectorAll(). Откройте в браузере инструменты разработчика / JavaScript console и введите, например,

document.querySelectorAll("meta[name='description']")

, чтобы получить все теги meta страницы с атрибутом name, который имеет значение description. См. Дополнительные сведения о CSS селекторах .

Помните об этом, потому что 1. вы лучше понимаете, на что смотрите / пытаетесь сделать 1. вы можете на самом деле используйте этот тип селекторов с BeautifulSoup!

С BeautifulSoup

Таким образом, вы можете переместить проверку атрибута name вверх в запросе. Что-то вроде

    metas = soup.find_all('meta', attrs={"name": "description"})

, и это должно дать вам только тегов, в которых есть name=description. Это означает, что все остальные <meta> будут проигнорированы.

В качестве альтернативы вы можете сохранить текущий метод запроса (получить все <meta> s) и просто игнорировать их в операторе if/else, т.е. не сохраняйте их в списке результатов. Если вы хотите знать, что он на самом деле что-то делает , но он просто не соответствует вашему запросу, вы можете просто зарегистрировать сообщение, вместо того, чтобы сохранять "Not Found".

0 голосов
/ 27 мая 2020

дайте мне знать, работает ли это для вас!

URL_List = ['https://digisapient.com', 'https://dataquest.io']
Meta_Description = []
meta_flag = False

for url in URL_List:
    response = requests.get(url, headers=headers)
    meta_flag = False
    #lower_response_text = response.text.lower()
    soup = BeautifulSoup(response.text, 'lxml')
    metas = soup.find_all('meta')
    for m in metas:
        if m.get ('name') == 'description':
            desc = m.get('content')
            Meta_Description.append(desc)
            meta_flag = True
            continue
    if not meta_flag:
        desc = "Not Found"
        Meta_Description.append(desc)

Идея кода заключается в том, что он будет перебирать все элементы в metas, если «описание» найдено, оно будет установить флаг в True, тем самым пропуская последующий if-оператор. Если после итерации через metas ничего не найдено, он добавит «Не найдено» к Meta_Description.

...