El rastreador direccional de clasificación de universidades chinas se refiere a los problemas y soluciones encontrados en el curso de rastreo de Python del profesor Songtian

Primero, adjunte el programa en el curso, no se puede ejecutar normalmente

Cambie la URL de 2016 por la URL de este año: http://www.shanghairanking.cn/rankings/bcur/2020

el código se muestra a continuación:

import requests
from bs4 import BeautifulSoup
import bs4

def getHTMLText(url):
    try:
        r = requests.get(url, timeout=30)
        r.raise_for_status()
        r.encoding = r.apparent_encoding
        return r.text
    except:
        return ""

def fillUnivList(ulist, html):
    soup = BeautifulSoup(html, "html.parser")
    for tr in soup.find('tbody').children:
        if isinstance(tr, bs4.element.Tag):
            tds = tr('td')
            ulist.append([tds[0].string, tds[1].string, tds[3].string])

def printUnivList(ulist, num):
    print("{:^10}\t{:^6}\t{:^10}".format("排名","学校名称","总分"))
    for i in range(num):
        u=ulist[i]
        print("{:^10}\t{:^6}\t{:^10}".format(u[0],u[1],u[2]))
    
def main():
    uinfo = []
    url = 'http://www.shanghairanking.cn/rankings/bcur/2020'
    html = getHTMLText(url)
    fillUnivList(uinfo, html)
    printUnivList(uinfo, 20) # 20 univs
main()

Resultado de salida:

报错
AttributeError: el objeto 'NoneType' no tiene atributo 'children'

Encuentra la causa del problema

Primero genere el contenido del sitio web, el código es el siguiente:

from bs4 import BeautifulSoup
import requests
r = requests.get('https://www.shanghairanking.cn/rankings/bcur/2020')
r.encoding = r.apparent_encoding
demo = r.text
soup = BeautifulSoup(demo,'html.parser')
print(soup.prettify())

Parte del resultado:

Interceptar parte del resultado de salida
En el resultado de salida, puede ver que la etiqueta tbody contiene la información de todas las universidades, la etiqueta tr contiene toda la información de una universidad y la etiqueta td contiene cada información de una sola universidad. Pero la diferencia con el material didáctico de Songtian es que la etiqueta que contiene el nombre de la universidad es la etiqueta a debajo de td.
Entonces, el problema debería ser parte de obtener el nombre de la universidad.
Imprima el contenido de la lista impresa.

el código se muestra a continuación:

La declaración:

ulist.append([tds[0].string, tds[1].string, tds[4].string])

A:

ulist.append([tds[0].string, tds[1], tds[4].string])
def fillUnivList(ulist, html):
    soup = BeautifulSoup(html, "html.parser")
    for tr in soup.find('tbody').children:
        if isinstance(tr, bs4.element.Tag):
            tds = tr('td')
            ulist.append([tds[0].string, tds[1], tds[4].string])
    print(ulist)

Resultado de salida:

Inserte la descripción de la imagen aquí
Puede ver que el contenido que queremos está impreso, pero hay algo que no queremos.
Puede ver que el contenido que queremos está bajo la etiqueta a, y podemos usar el método .find () para recuperar el contenido que queremos.

el código se muestra a continuación:

for a in tr.find('a'):
	print('a')

La salida es:

Inserte la descripción de la imagen aquí
Esto es exactamente lo que queremos y lo asignamos a tds.

el código se muestra a continuación:

def fillUnivList(ulist, html):
    soup = BeautifulSoup(html, "html.parser")
    for tr in soup.find('tbody').children:
        if isinstance(tr, bs4.element.Tag):
            tds = tr('td')
#            ulist.append([tds[0].string, tds[1], tds[4].string])
            for a in tr.find('a'):
#                print(a)
                ulist.append([tds[0].string, a, tds[4].string])

La salida es:

Inserte la descripción de la imagen aquí
El contenido es exactamente lo que queremos, pero el diseño no es lo suficientemente ordenado. La razón es que el contenido de ulist contiene saltos de línea.
Reemplace el carácter de nueva línea en ulist con el método .replace (), y no habrá problema de nueva línea.

el código se muestra a continuación:

def printUnivList(ulist, num):
    print("{:^10}\t{:^6}\t{:^10}".format("排名","学校名称","总分"))
    for i in range(num):
        u=ulist[i]
        print("{:^10}\t{:^6}\t{:^10}".format(u[0].replace('\n',''), u[1].replace('\n',''), u[2].replace('\n','')))

Resultado de salida:

Inserte la descripción de la imagen aquí
Esta es exactamente la composición tipográfica y el contenido que queremos. Modifique el formato impreso por print () para obtener una composición tipográfica más ordenada.

El código general del programa es el siguiente:

import requests
from bs4 import BeautifulSoup
import bs4

def getHTMLText(url):
    try:
        r = requests.get(url, timeout=30)
        r.raise_for_status()
        r.encoding = r.apparent_encoding
        return r.text
    except:
        return ""

def fillUnivList(ulist, html):
    soup = BeautifulSoup(html, "html.parser")
    for tr in soup.find('tbody').children:
        if isinstance(tr, bs4.element.Tag):
            tds = tr('td')
#            ulist.append([tds[0].string, tds[1], tds[4].string])
            for a in tr.find('a'):
#                print(a)
                ulist.append([tds[0].string, a, tds[4].string])
    
def printUnivList(ulist, num):
    print("     {:^10}\t{:^6}\t      {:^10}".format("排名","学校名称","总分"))
    for i in range(num):
        u=ulist[i]
        print("{:^10}\t{:^6}\t{:^10}".format(u[0].replace('\n',''), u[1].replace('\n',''), u[2].replace('\n','')))
    
def main():
    uinfo = []
    url = 'http://www.shanghairanking.cn/rankings/bcur/2020'
    html = getHTMLText(url)
    fillUnivList(uinfo, html)
    printUnivList(uinfo, 20) # 20 univs
main()

La salida es:

Inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/qq_51005828/article/details/109405304
Recomendado
Clasificación