“爬取大学排名”实例

知识及技巧储备

  1. 获取源码:选中右键检查-选中右键复制selector

  2. nth-of-type(1)和nth-of-children(1):nth-of-type(1) 选择器指定的是标签

  3. 确定标签从属关系:选中右键检查-上移并对比左侧原网页

  4. r.raise_for_status():只检查响应状态码,不打印,通过即继续下一代码,不通过即返回空字符串return""

  5. if isinstance(tr, bs4.element.Tag):isinstance函数是python自带的函数,用于判断对象类型,用其检验对象是否为bs4对象时,需引用import bs4

  6. soup.find('tbody')等价于soup.tbody:都只返回找到的第一个tbody,这是一个bs4对象可以直接调用bs4函数

  7. soup.find_all('tbody'):返回的是一个列表,需对其中每一个对象进行处理,如for tbody in soup.find_all('tbody'),同理.select()返回的也是一个列表.
    [1]  第6、7条总结来说soup.find('tbody') 和 soup.tbody 只返回第一个 <tbody> soup.find_all('tbody') 和 soup('tbody') 返回所有 <tbody> 标签的列表。 soup.select('tbody') 也返回所有 <tbody> 标签的列表,且支持更复杂的 CSS 选择器语法。

  8. zip()函数:将多个可迭代对象(如列表)中的元素逐一配对聚合成一个元组的迭代器

  9. .strip() 方法:移除字符串两端的空白字符

  10. 中文字符对齐问题:format方法中{1:{3}^10} 是一个嵌套的格式化说明符, Python 3.6 以上版本支持。{3}: 表示填充字符来自于 format() 方法中的第四个参数(索引为 3)。

find方法爬取

import requests
from bs4 import BeautifulSoup
import bs4
​
#获取url信息,输出html格式的内容
def getHTMLText(url):
    try: #try except 结构规定这个函数的结构框架
        r = requests.get(url, timeout=30)
        r.raise_for_status() #产生异常信息
        r.encoding = r.apparent_encoding
        return r.text
    except:
        return "" #如果出现错误,返回空字符串
​
#将url内容放在大学列表中
def fillUnivList(ulist,html):
    soup = BeautifulSoup(html, "html.parser")
    #原网页界面选中清华大学右键"检查"-源码中对应span标签-源码中由span上移逐渐对应原界面中整个清华大学的信息-找到tr标签
    #找到层级关系 tbody-tr-td
    #找到tbody获取所有大学信息-再解析tr标签获取每个大学信息-解析td标签获取每个参数信息
    for tbody in soup.find_all('tbody'):
        #isinstance函数是bs4库中的函数,需引用该库
        for tr in tbody.find_all("tr"):
        if isinstance(tr, bs4.element.Tag):
            tds = tr.find_all('td')
            span = tds[1].find_all('div')[0]
            span = span.find_all('div')[2]
            span = span.find_all('div')[0]
            span = span.find_all('div')[0]
            span = span.find_all('span')[0]
​
            ulist.append([tds[0].string,span.string, tds[4].string])
​
​
#将列表的内容规范格式打出来,打印num个学校
def printUnivList(ulist,num):
    tplt = "{0:^12}\t{1:{3}^28}\t{2:^12}"
    print(tplt.format("排名", "学校名称", "总分", chr(12288)))
    for i in range(num):
        u = ulist[i]
        print(tplt.format(u[0].strip(), u[1].strip(), u[2].strip(), chr(12288)))
​
def main():
    uinfo = [] #收集大学信息的列表
    url = "https://www.shanghairanking.cn/rankings/bcur/2016"
    html = getHTMLText(url)
    fillUnivList(uinfo, html)
    printUnivList(uinfo,20)
main()
​
​

select方法爬取

import requests
from bs4 import BeautifulSoup
import bs4
​
#获取url信息,输出html格式的内容
def getHTMLText(url):
    try: #try except 结构规定这个函数的结构框架
        r = requests.get(url, timeout=30)
        r.raise_for_status() #产生异常信息
        r.encoding = r.apparent_encoding
        return r.text
    except:
        return "" #如果出现错误,返回空字符串
​
#将url内容放在大学列表中
def fillUnivList(uinfo,html):
    soup = BeautifulSoup(html, "html.parser")
    #原网页界面选中清华大学右键"检查"-源码中对应span标签-源码中由span上移逐渐对应原界面中整个清华大学的信息-找到tr标签
    #找到层级关系 tbody-tr-td
    #找到tbody获取所有大学信息-再解析tr标签获取每个大学信息-解析td标签获取每个参数信息
    for tr in soup.tbody.find_all('tr',recursive=False):
        #isinstance函数是bs4库中的函数,需引用该库
        if isinstance(tr, bs4.element.Tag):
            ranks = tr.select("td:nth-of-type(1) > div")
            names = tr.select("td.align-left > div > div.univname > div:nth-of-type(1) > div > div > span")
            scores = tr.select("td:nth-of-type(5)")
            for rank, name, score in zip(ranks, names, scores):
                data={'rank':rank.get_text(), 'name':name.get_text(), 'score':score.get_text()}
                uinfo.append(data)
​
​
#将列表的内容规范格式打出来,打印num个学校
def printUnivList(uinfo,num):
    print("{0:^10}\t{1:{3}^10}\t{2:^10}".format("排名", "学校名称", "总分", chr(12288))+'\n')
    num = min(num, len(uinfo))
    for i in range(num):
        u = uinfo[i]
        print("{0:^10}\t{1:{3}^10}\t{2:^10}".format(u['rank'].strip(), u['name'].strip(), u['score'].strip(), chr(12288))+'\n')
​
    print("Suc"+str(num))
​
def main():
    uinfo = [] #收集大学信息的列表
    url = "https://www.shanghairanking.cn/rankings/bcur/2016"
    html = getHTMLText(url)
    fillUnivList(uinfo, html)
    printUnivList(uinfo,20)
main()
​
​


我的小秘~~