这是要爬取的网址
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中打开格式会更好