Как я могу получить данные из указанного c текста в классе div с помощью BeautifulSoup - PullRequest
0 голосов
/ 09 июля 2020

Я только что разработал Scrapper с помощью python. Я хочу очистить какой-то текст на домашней странице, и я написал такой код, чтобы получить определенные c тестовые данные, но он ничего не возвращает.

Это часть html, где я хочу to scape

<div class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content-active" id="ui-id-94" aria-labelledby="ui-id-93" role="tabpanel" aria-hidden="false" style="display: block; height: 210px;">
<p>
    <a href="/programs-courses/catalogue/programs/PBDCIS">Computer and Information Systems (Post-Baccalaureate Diploma)</a>
    <a href="/programs-courses/catalogue/programs/DPCSTI">Computing Studies and Information Systems (Diploma)</a>
    <a href="/programs-courses/catalogue/programs/PDDATA">Data Analytics (Post-Degree Diploma)</a>
    <a href="/programs-courses/catalogue/programs/ACTCSI_DA">Data and Analytics</a>
    <a href="/programs-courses/catalogue/programs/PDEMTC">Emerging Technology (Post-Degree Diploma)</a>
    <a href="/programs-courses/catalogue/programs/PDICT">Information and Communication Technology (Post-Degree Diploma) </a>
    <a href="/programs-courses/catalogue/programs/ACTCSI_WEB">Web and Mobile Computing</a>
</p>

Я хочу получить имена программ, я кодирую вот так, но он возвращает пустой список.

from bs4 import BeautifulSoup
import requests
import os
import re
import sys

URL = "https://www.douglascollege.ca/programs-courses/catalogue/programs"

    r = requests.get(URL, headers = self.requestHeaders())
    soup = BeautifulSoup(r.text, "html.parser")

    test = soup.find_all("a", class_='ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content-active')

    print(test)

в чем проблема ...?

Ответы [ 3 ]

1 голос
/ 09 июля 2020

Первая проблема: на этой странице используются JavaScript и requests, Beautifulsoup не может работать JavaScript. Вам может потребоваться Selenium для управления веб-браузером, который может запускать JavaScript. И он может дать вам полный HTML, который вы можете искать с помощью Selenium или использовать с Beautifulsoup

Вторая проблема: вам нужно искать div с этими классами, а затем внутри div, у вас есть для поиска a без этих классов.

Кстати: для управления браузером у вас также будет драйвер для Firefox или Chrome

Код:

import selenium.webdriver
from bs4 import BeautifulSoup

url = "https://www.douglascollege.ca/programs-courses/catalogue/programs"

driver = selenium.webdriver.Firefox()
driver.get(url)

soup = BeautifulSoup(driver.page_source, "html.parser")

all_div = soup.find_all("div", class_='ui-accordion-content')

for div in all_div:
    all_items = div.find_all("a")

    for item in all_items:
        print(item.text)

Часть результата:

Basic Occupational Education - Electronics and General Assembly
Basic Occupational Education - Food Services
Basic Occupational Education - Retail and Business Services
Child and Youth Care (Bachelor of Arts)
Child and Youth Care (Diploma)

Classroom and Community Support (Certificate)
Classroom and Community Support (Diploma)
Education Assistance and Inclusion (Certificate)
Early Childhood Education (Certificate)
Early Childhood Education (Diploma) 
Early Childhood Education: Infant/Toddler (Post-Basic Certificate)
Early Childhood Education: Special Needs - Inclusive Practices (Post-Basic Certificate)
Employment Supports Specialty
Therapeutic Recreation (Bachelor)
Therapeutic Recreation (Diploma)
Accounting (Bachelor of Business Administration)
Accounting (Certificate)

РЕДАКТИРОВАТЬ: То же, без BeautifulSoup, используя только Selenium

import selenium.webdriver

url = "https://www.douglascollege.ca/programs-courses/catalogue/programs"

driver = selenium.webdriver.Firefox()
driver.get(url)

all_div = driver.find_elements_by_xpath('//div[contains(@class, "ui-accordion-content")]')

for div in all_div:
    all_items = div.find_elements_by_tag_name("a")

    for item in all_items:
        print(item.get_attribute('textContent'))
        #print(item.text) # doesn't work for hidden element
1 голос
/ 09 июля 2020

Ваш вызов soup.find_all() ищет элементы «a» с классами ui-accordion-content, ui-helper-reset, et c, но ни один из этих элементов «a» не имеет этих классов. Попробуйте удалить часть класса.

0 голосов
/ 09 июля 2020

Я могу ошибаться, но похоже, что страница, которую вы пытаетесь очистить, имеет javascript, что означает, что BS не справится с этой задачей. Когда я упрощаю код, чтобы вернуть весь суп, он должен вернуть все html. Итак, следующее:

from bs4 import BeautifulSoup
import requests
import os
import re
import sys

URL = "https://www.douglascollege.ca/programs-courses/catalogue/programs"
r = requests.get(URL)
coverpage = r.content
soup = BeautifulSoup(coverpage, 'html5lib')
print(soup)

дает

<html><head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr/><center>Microsoft-Azure-Application-Gateway/v2</center>


</body></html>

Вот почему вы не получаете никаких <a>, потому что их нет в супе.

Если URL-адрес изменен на что-то другое, например:

URL = "https://www.tutorialspoint.com/gensim/gensim_creating_lda_mallet_model.htm"

URL-адрес возвращает html страницы, вызывая суп, а затем есть <a>, которые нужно получить.

При просмотре источника страницы, которую вы пытаетесь очистить, появляется эта строка

<script src="/-/media/A1FA8497F6534B7D915442DEC3FA6541.ashx?636948345000000000"></script><script src="/-/media/ACA0B6DEC2124962B48341E8092B8B4D.ashx?636948345010000000"></script><script src="/-/media/68BA4C1C2A0D494F97E7CD7D5ECE72B0.ashx?637036665710000000"></script>
<!-- Javascripts goes between here -->

Наряду с несколькими другими упоминаниями javascript на странице. Как обсуждалось в этом вопросе , вы можете попробовать Selenium, а не BS. Удачи.

...