【问题标题】:Asking the user to input something and use Beautiful Soup to parse a website要求用户输入内容并使用 Beautiful Soup 解析网站
【发布时间】:2019-12-01 10:45:31
【问题描述】:

我应该使用 Beautiful Soup 4 从我学校的网站上获取课程信息作为练习。过去几天我一直在这,我的代码仍然无法正常工作。

我要求用户的第一件事是导入课程目录缩写。例如,ICS 缩写为 Information for Computer Science。 Beautiful Soup 4 应该列出所有的课程以及有多少学生注册。

虽然我能够让输入部分工作,但我仍然有错误或程序停止。

问题:Beautiful Soup 有没有办法接受用户输入,这样当用户输入 ICS 时,输出将是与 ICS 相关的所有课程的列表?

这是代码和我的尝试:

from bs4 import BeautifulSoup
import requests
import re

#get input for course
course = input('Enter the course:')
#Here is the page link
BASE_AVAILABILITY_URL = f"https://www.sis.hawaii.edu/uhdad/avail.classes?i=MAN&t=202010&s={course}"


#get request and response
page_response = requests.get(BASE_AVAILABILITY_URL)
#getting Beautiful Soup to gather the html content
page_content = BeautifulSoup(page_response.content, 'html.parser')
#getting course information
main = page_content.find_all(class_='parent clearfix')
main_p = "".join(str (x) for x in main)
#get the course anchor tags
main_q = BeautifulSoup(main_p, "html.parser")
courses = main.find('a', href = True)
#get each course name
#empty dictionary for course list
courses_list = []
for a in courses:
    courses_list.append(a.text)
    search = input('Enter the course title:')
for course in courses_list:
    if re.search(search, course, re.IGNORECASE):
        print(course)

这是 Juypter Notebook 中提供的原始代码

import requests, bs4

BASE_AVAILABILITY_URL = f"https://www.sis.hawaii.edu/uhdad/avail.classes?i=MAN&t=202010&s={course}"
#get input for course
course = input('Enter the course:')



def scrape_availability(text):
    soup = bs4.BeautifulSoup(text)
    r = requests.get(str(BASE_AVAILABILITY_URL)  + str(course))
    rows = soup.select('.listOfClasses tr')

    for row in rows[1:]:
        columns = row.select('td')
        class_name = columns[2].contents[0]
        if len(class_name) > 1 and class_name != b'\xa0':
            print(class_name)
            print(columns[4].contents[0])
            print(columns[7].contents[0])
            print(columns[8].contents[0])

奇怪的是,如果用户保存 html 文件,将其上传到 Juypter Notebook,然后打开要阅读的文件,就会显示课程。但是,对于这个任务,用户不能保存文件,它必须是一个直接的输入才能得到输出。

【问题讨论】:

  • “我仍然有错误或程序刚刚停止” - 一个特定的错误会告诉您失败的原因和原因。不要只是在看到错误消息时放弃。阅读并理解消息,使用其信息来理解和纠正问题。那么......错误是什么?具体发生在哪里?发生时的运行时值是多少?
  • @David 起初这是一个未定义的东西,这让我意识到代码顺序是错误的。在较早的一次尝试中,我在输入之前先打开了 url,而它应该是相反的。现在的问题是确定输入框已经显示,但是在我输入课程缩写之后,在这种情况下是 ICS,没有任何反应。它特别发生在我输入课程之后。
  • @David 我知道有关于 Beautiful Soup 的教程,但没有一个是在谈论我需要做什么。到目前为止,我看到的所有教程都有这个 url = 'http:// 不管它是什么',我知道这是固定的,这意味着我不能有用户输入。 So Beautiful Soup 将解析 url,这取决于需要抓取/解析的内容
  • 现在是进行调试的时候了。 “什么都没有发生”是一个有点行不通的事情。在没有调试器的情况下,您可以做的一件事是在整个代码中添加各种输出行。您可以输出各种运行时值、指示已到达哪些代码块的输出行等。代码不会“停止”。它要么以异常退出,要么执行到逻辑完成。例如,获得用户输入后的每一行都在创造一个价值。这些价值观最终是什么?
  • @chitown88 在本学期早些时候,我被教导了 python 的输入,它是 testing = input('Type hi:') 然后当我在 Juypter Notebook 上运行它时它会起作用现在,我需要将输入带入网站的 url 但要做到这一点,我需要 course = input('Enter the course letters:') 通常没有 url,代码只会给出一个框并要求用户输入课程字母...但是现在我需要输入将要放置在 url 中的课程字母,因此输出将是正在访问并打印课程的 url

标签: python python-3.x beautifulsoup python-requests


【解决方案1】:

您的代码的问题是page_content.find_all(class_='parent clearfix') retuns 和空列表[]。所以这是你需要改变的第一件事。查看 html,您会想要寻找 <table><tr><td>、标签

处理原始代码提供的内容,您只需要更改一些内容以符合逻辑:

我会指出我改变了什么:

import requests, bs4

BASE_AVAILABILITY_URL = f"https://www.sis.hawaii.edu/uhdad/avail.classes?i=MAN&t=202010&s={course}"
#get input for course
course = input('Enter the course:')



def scrape_availability(text):
    soup = bs4.BeautifulSoup(text)   #<-- need to get the html text before creating a bs4 object. So I move the request (line below) before this, and also adjusted the parameter for this function.
                                     # the rest of the code is fine
    r = requests.get(str(BASE_AVAILABILITY_URL)  + str(course))
    rows = soup.select('.listOfClasses tr')

    for row in rows[1:]:
        columns = row.select('td')
        class_name = columns[2].contents[0]
        if len(class_name) > 1 and class_name != b'\xa0':
            print(class_name)
            print(columns[4].contents[0])
            print(columns[7].contents[0])
            print(columns[8].contents[0])

这会给你:

import requests, bs4

BASE_AVAILABILITY_URL = "https://www.sis.hawaii.edu/uhdad/avail.classes?i=MAN&t=202010&s="
#get input for course
course = input('Enter the course:')

url = BASE_AVAILABILITY_URL  + course

def scrape_availability(url):

    r = requests.get(url)
    soup = bs4.BeautifulSoup(r.text, 'html.parser')
    rows = soup.select('.listOfClasses tr')

    for row in rows[1:]:
        columns = row.select('td')
        class_name = columns[2].contents[0]
        if len(class_name) > 1 and class_name != b'\xa0':
            print(class_name)
            print(columns[4].contents[0])
            print(columns[7].contents[0])
            print(columns[8].contents[0])



scrape_availability(url)            

【讨论】:

  • 有效!我被困了一段时间。我猜代码中的顺序很重要,因为当我多次这样做时,输出什么都没有。现在,我只需要为注册的学生人数和可用座位制作标签。谢谢您的帮助! :)
  • 好。我希望这是有道理的。在实际获取 html r = requests.get(url) 之前,您实际上是在尝试解析 html soup = bs4.BeautifulSoup(r.text, 'html.parser')。有点像在启动引擎之前尝试开车。
猜你喜欢
  • 1970-01-01
  • 2019-03-06
  • 1970-01-01
  • 2017-07-20
  • 2012-06-29
  • 1970-01-01
  • 2023-03-24
  • 1970-01-01
  • 2015-11-08
相关资源
最近更新 更多