实例2 爬取大学排名
上海交通大学设计了一个“最好大学网”,上面列出了当前的大学排名。我们要设计爬虫程序,爬取大学排名信息。
爬虫功能要求:
输入:大学排名URL链接
输出:大学排名信息的屏幕输出(排名,大学名称,总分)
工具:python3、requests、beautifulsoup
程序设计思路:
- 研究大学排名网站网页URL
- 设计fetchUrl函数,尝试获取页面;
- 设计parseHtml函数,解析内容;
- 设计output函数,组织列表形式输出;
- 使用main函数调用程序。
import re
import requests
import bs4
def fetchUrl(url):
'''
功能:根据参数 url ,发起 http request,尝试获取指定网页并返回结果
参数:
url:某个 webpage 的url
返回:类文件对象型 http Response 对象
'''
headers = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'
}
try:
r = requests.get(url, headers=headers)
r.raise_for_status()
r.encoding = r.apparent_encoding
print('success!')
return r.text
except requests.RequestError as e:
print(e)
except:
return "Error!"
def parserHtml(html,urating):
'''
功能:根据参数 html 给定的内存型 HTML 文件,尝试解析其结构,获取所需内容
参数:
html:类似文件的内存 HTML 文本对象
urating:一个二维列表,存放着大学排名信息
返回:一个二维列表,存放着大学排名信息
'''
bsobj = bs4.BeautifulSoup(html,'html.parser')
# 获取表头信息
tr = bsobj.find('thead').find('tr')
hlist = []
if isinstance(tr, bs4.element.Tag):
for th in tr('th'):
hlist.append(th.string)
hlist.pop()
for option in tr('option'):
hlist.append(option.string)
urating.append(hlist)
# 获取表体信息
for tr in bsobj.find('tbody').children:
blist = []
if isinstance(tr, bs4.element.Tag):
for td in tr('td'):
blist.append(td.string)
urating.append(blist)
return urating
def output(urating, filename):
'''
功能:格式化输出结果
参数:
urating:存放着排名结果的二维列表
filename:保存的文件名
返回:无
'''
import pandas as pd
dataframe = pd.DataFrame(urating)
dataframe.to_csv(filename, index=False, sep=',', header=False)
print("Success!")
def main():
url = 'http://www.zuihaodaxue.cn/zuihaodaxuepaiming2018.html'
print("Begin to crawl the http://www.zuihaodaxue.cn/zuihaodaxuepaiming2018.html and get the rating of universities in china ...")
print('---'*20)
print("Try to fetch url ...")
html = fetchUrl(url)
print("Try to parser html ...")
urating = []
ur = parserHtml(html,urating)
print("Try to save the results in file ...")
output(ur, '大学排名2018.csv')
print("The work of crawling is done.")
if __name__ == '__main__':
main()
Begin to crawl the http://www.zuihaodaxue.cn/zuihaodaxuepaiming2018.html and get the rating of universities in china ...
------------------------------------------------------------
Try to fetch url ...
success!
Try to parser html ...
Try to save the results in file ...
Success!
The work of crawling is done.
在程序实现的时候,其实也是遇到了一些小坑,需要花一些小心思的。
就是分析网页的时候,发现表格最后一栏(得分指标)居然是一个下拉框,里面有很多指标选项,而且选择不同的指标,表格中显示的数据也不同。我需要根据它的实现原理来制定响应的爬取策略。
首先排除 url(因为整个过程中 url 是一直没有变过),其次查看是否是 Ajax 异步加载,打开开发者工具监测网页,发现在切换指标选项时,并没有发出新的请求,说明数据是一开始就已经获取好了的。随后查看 Element ,定位到指标得分的这一列,然后发现...
果然各个指标的数据都是有的,只是在页面中隐藏了而已,所以,找好位置,可以放心的直接爬了(有一个小插曲,就是我担心这些数据排列的顺序跟表头里指标的顺序不一致而造成错误,但是后来对应着表格里的数据,验证了几行,发现这个担心是多余的)。
我觉得做爬虫最关键的并不是做好某一个特定的爬虫程序,最重要的是思路,虽然这里的担心是多余的,但是有这个警觉性是很有必要的。