这是要爬取的网址
http://www.zuihaodaxue.com/zuihaodaxuepaiming2018.html
效果如下,代码思路均来自于中国大学mooc python嵩老师的课程(推荐一下)

前置知识

python基本语法,看得懂html (找到要爬取的内容)
简单的request(爬虫工具,不会也没关系)
beautifulsoup(将爬下的内容转换为人看的懂的工具,这是核心,有注释,但要理解清楚还得再多看点文章)
如果以上都问题不大,那么接下来将会很轻松(如果你水平可以,你也可以直接看文末代码)

代码框架

#获取网页内容
def getHTML(url):
#将网页中目标内容移动到列表中
def moveToList():
#打印
def printHTML():
main():
	url="http://www.zuihaodaxue.com/zuihaodaxuepaiming2018.html"
	uinfo=[]
	html=getHTML(url)
	moveToList(uinfo,html)
	printHTML(uinfo,20)

以上是整个代码的骨架,思路很清晰,我始终认为,代码骨架可以使得思路清晰,比起具体的代码有更少的记忆负担和更好的效果

核心分析

request和beautifulsoup都是需要导入的,所以我们还得


import requests
from bs4 import BeautifulSoup
import bs4

为什么要导入两次bs4?不是的,一次是BeautifulSoup,用来解析爬下来的内容,
一次是bs4,用来过滤无关的内容

有三个知识核心,看这个代码

#将url这个网址的html内容返回到r中
r=request.get(url)

print(r.text)就可以直接打印出html代码,这是最简单的爬虫

# 将html文件使用html解析器进行解析,返回的soup就是排好格式的html,
    soup = BeautifulSoup(html, "html.parser")

这是承接上面的,注意,此时soup仍是html

#在soup对象中寻找<tbody>标签的子标签
    for tr in soup.find('tbody').children:

为什么是tbody?因为

网页上面的大学都在tbody里面,而tbody有很多的tr,就是一行大学,包括名字,省份,排名等
所以tbody的子标签就是tr,但是不是所有的tr都是大学,还得过滤(代码有介绍)

最后是是将过滤好的数据转换格式

#将“排名”房子0处,“学校名称”放在1处,省份放在2处
#^表示居中,<表示居左,后面的数字表示占位大小
#chr(12288)表示用中文的空格补齐空缺(避免错位)
	tplt="{0:^6}\t{1:{3}^10}\t{2:<10}"
    print(tplt.format("排名", "学校名称", "省份",chr(12288)))

如果你已经理解了以上3个核心问题,那么你就可以直接看代码了

源代码

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2019/2/13 13:33
# @Author  : cs
# @decription:  爬取中国最好大学排名

import requests
from bs4 import BeautifulSoup
import bs4
from pandas import DataFrame

def getHTML(url):
    try:
        r = requests.get(url, timeout=30)
        r.raise_for_status()
        #解码格式
        r.encoding = r.apparent_encoding
        return r.text
    except:
        print("获取错误")


def moveToList(ulist, html):
    soup = BeautifulSoup(html, "html.parser")
    # print(soup.find('tbody').childern)
    # 找到目标数据标签,遍历tbody的孩子
    for tr in soup.find('tbody').children:
        # 过滤,如果tr的类型是bs4.element.Tag,那就是目标类型
        if isinstance(tr, bs4.element.Tag):
            # print(tr)
            #将所有td标签(列值)存储到列表中
            tds = tr('td')
            # 将每个列表添加到大列表中作为一个元素,只取前三列(排名,大学,省份)的string(内容)
            ulist.append([tds[0].string, tds[1].string, tds[2].string])

def printHTML(ulist,num):
    tplt="{0:^6}\t{1:{3}^10}\t{2:<10}"
    print(tplt.format("排名", "学校名称", "省份",chr(12288)))
    for i in range(num):
        u=ulist[i]
        print(tplt.format(u[0], u[1], u[2],chr(12288)))
    pass


def main():
    url = "http://www.zuihaodaxue.com/zuihaodaxuepaiming2018.html"
    html = getHTML(url)
    # print(html)
    uinfo = []
    moveToList(uinfo, html)
    frame=DataFrame(uinfo)
   #这里可以将内容输出到csv文件,data是项目下的包,修改相对路劲即可
    #frame.to_csv("../data/bestUniversity.csv",index=0)
    printHTML(uinfo,20)
main()

这是在pycharm中打开的csv文件,在wps中打开格式会更好