实战练习1:爬取中国大学排名前20
大家可以关注知乎或微信公众号的‘share16’,我们也会同步更新此文章。
一、思路如下
- 查看相关网站的Robots协议(robots.txt),如https://xxxxxxx.com/robots.txt ;
- 从网络上获取大学排名网页的内容,定义函数为 getHTMLText(url) ;
- 提取网页内容中的信息,并添加到合适的数据结构,定义函数为 fillUnivList(ulist,html) ;
- 利用数据结构提取数据并输出结果,定义函数为 printUnivList(ulist,num) ;
二、要爬取的网站
中国大学排名 (http://xxxxxxxxx/xxxx/xxxx.html)
ps: 涉及到版权问题,后续烦请大家自行搜索呀。😁😁😁
三、网页源代码分析
- 在中国大学排名网,了解到 ‘排名第一的是清华大学、总分969.2’
- 鼠标右击 - 显示页面源文件
- 在源文件页,搜索 ‘969.2’,查看得知:“ 每一行排名都在一个tbody.tr标签内、每行排名内的每个单元格的内容都在一个td标签内 ”,如下图:
四、代码如下
4-1. 获取网页内容:
requests.get() # 获取HTML网页内容的方法
r 是Response对象,下面是Response对象的属性:
r.raise_for_status() #若Response类型状态不是200,会产生一个HttpError的异常。
r.text #返回url对应的页面内容,其是str类型。
r.encoding #从http header中猜测的响应内容编码方式,一般是’ISO-8859-1’(不能识别中文)。
r.apparent_encoding #从内容中分析出响应内容编码方式,如:utf-8、GB2312等。
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
html = r.text
except:
html = '爬取失败'
return html
4-2. 提取相关内容,储存到列表中:
soup.tbody.contents #将soup.tbody的所有子节点存入列表
isinstance(tr, bs4.element.Tag) #判断子标签是否为Tag对象(因为子节点会包含如换行符之类的节点)
def fillUnivList(ulist,html):
soup = BeautifulSoup(html,'html.parser')
data = soup.tbody.contents
for tr in data:
if isinstance(tr, bs4.element.Tag):
tds = tr.find_all('td')
ulist.append([ tds[0].div.string, tds[1].find(name='a', attrs= {'class':'name-cn'}).string,
tds[2].get_text(), tds[3].get_text(), tds[4].string, tds[5].string])
else:
pass
4-3. 打印结果(format格式化函数):
def printUnivList(ulist,num):
cols = "{0:{6}^10}\t{1:{6}^10}\t{2:{6}^10}\t{3:{6}^10}\t{4:^10}\t{5:^10}\t"
print(cols.format('排名','大学名称','省市','类型','总分','办学层次',chr(12288)))
for k in range(num):
i = ulist[k]
print(cols.format(str(i[0]).strip(),str(i[1]).strip(),str(i[2]).strip(),str(i[3]).strip(),str(i[4]).strip(),str(i[5]).strip(),chr(12288)))
4-4. 主函数,调用上述几个函数:
def main():
ulist = []
url = 'http://xxxxxxxxx/xxxx/xxxx.html'
html = getHTMLText(url)
fillUnivList(ulist,html)
printUnivList(ulist,20)
main()
4-5. 运行结果:
谢谢大家🌹