1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 嵩天《Python网络爬虫与信息提取》实例2:中国大学排名定向爬虫

嵩天《Python网络爬虫与信息提取》实例2:中国大学排名定向爬虫

时间:2020-01-08 10:15:35

相关推荐

嵩天《Python网络爬虫与信息提取》实例2:中国大学排名定向爬虫

在介绍完requests库和robots协议后,嵩天老师又重点介绍了如何通过BeautifulSoup库进行网页解析和信息提取。这一部分就是在前面内容的基础上,综合运用requests库和BeautifulSoup库的知识,对软科中国大学排名进行定向爬取。

说明:爬虫练习仅为学习,不做商用,如有侵权,烦请联系删除!

目标网页:/rankings/bcur/

爬取目标:爬取上海软科官网提供的中国最好大学排名,并在IDLE页面打印输出大学名称、排名、省市、总分信息

相关库名:requests/BeautifulSoup

目录

1.网页解析

2.代码设计

3.运行结果

4.问题记录

1.网页解析

打开上述软科中国大学排名页面,选择最新的排名,页面显示如下:

查看页面源代码,Ctrl+F搜索北京大学,可以定位到与大学排名相关的代码位置,观察代码可知,所有的大学排名信息被封装在<tbody>标签中,其中每一个大学排名的信息则被封装在<tr>标签中,大学排名、大学名称、省市、总分等信息都封装在其下的<td>标签中,这里需要注意的是,新版的大学排名中,大学名称对应的td标签中还包括中英文校名、LOGO等信息,这些信息又分别封装在<a>标签中,所以要仅打印中文大学名称的话,需要具体到查找属性为'name-cn'的a标签并存储其字符串。

2.代码设计

结合新版的中国大学排名网页情况,对嵩天老师提供的中国大学排名爬虫源代码做了简单的修改,完整代码如下,相关讲解见注释:

#实例:中国大学排名定向爬虫import requestsfrom bs4 import BeautifulSoup#从beautifulsoup4库中引入BeautifulSoup类,注意大小写import bs4#注意这里需要再引入bs4库,因为后面有bs4.element.Tag语句,不引入会报错def getHTMLText(url):#定义获取网页源代码文本内容的函数try:r=requests.get(url,timeout=30)r.raise_for_status()r.encoding=r.apparent_encodingreturn r.textexcept:print('获取网页信息失败')def fillUnivList(ulist,html):#定义获取大学排名信息的函数soup=BeautifulSoup(html,'html.parser')#使用html.parser解析器解析返回的html源代码文本for tr in soup.find('tbody').children:#使用for循环查找tbody标签,并遍历其子孙节点if isinstance(tr,bs4.element.Tag):#检测是否为tag标签不是则过滤tds=tr('td')#查找tr标签下所有的td标签,并将其内容保存为tdsa=tr('a','name-cn')#由于新版的排名中,td下的大学名称信息还包括中英文校名、LOGO等,这些又分别封装在a标签中,所以这里需要具体到查找属性为'name-cn'的a标签并存储其字符串,即大学的中文名称ulist.append([tds[0].string.strip(),a[0].string.strip(),tds[2].text.strip(),tds[4].string.strip()])#依次将大学排名、大学名称、省市(这个用string会报错)、总分信息保存到列表中,使用.strip()删除结尾的字符def printUnivList(ulist,num):#定义打印大学排名信息的函数,这里的num值打印大学的数量printmode='{0:^10}\t{1:{4}^10}\t{2:{4}^10}\t{3:^10}'#引入一个输出模板的变量这里的{4}指代中文空格chr(12288),用以填充大学名称其余空格,使得输出的字符能够对齐,并且这里选择把字符长度都设置为10,否则表头和打印内容总是对不齐print(printmode.format('排名','大学名称','省市','总分',chr(12288)))#打印表头的信息并设置打印格式for i in range(num):u=ulist[i]#使用for循环依次打印ulist列表中存储的大学排名信息,用变量u代表每所大学的信息print(printmode.format(u[0],u[1],u[2],u[3],chr(12288)))#设置打印格式依次打印每所大学的排名、大学名称、省市、总分信息def main():uinfo=[]#定义一个空列表用于填充装取大学排名信息url='/rankings/bcur/'#给出大学排名网页html=getHTMLText(url)#调用函数获取网页源代码文本fillUnivList(uinfo,html)#调用函数获取大学排名信息并填充到列表中printUnivList(uinfo,30)#调用打印大学排名信息的函数,并打印排名前30的大学信息main()

3.运行结果

运行代码后,IDLE页面结果显示如下:

4.问题记录

这里再记录一些代码测试过程中的报错信息,首先是一个命名错误:

NameError: name 'bs4' is not defined

其实是因为后面if isinstance(tr,bs4.element.Tag)这里用到了bs4而我们只引入了bs4库中的BeautifulSoup类,再在开头加上import bs4单独引入bs4库就好了。

此外,省市的打印如果用.string的话会报错如下:

TypeError: unsupported format string passed to NoneType.__format__

即此时省市信息为None值无法有效打印,修改为.text就能正常打印省市信息了。

再者,如果按照嵩天老师的代码直接打印.string的字符信息的话,发现打印出的大学排名信息是没有对齐且跨行了的,如下图所示:

解决这一问题的方案是在.string后再加入.strip()删除结尾可能存在的多余的字符。

这些问题也都在上面的完整代码中对应位置作了相应说明。之前看慕课时也练习过这个案例,当时也遇到了挺多问题的,而且也不能完全理解全部代码的含义,在有了些许经验之后再回来练习,很快就调整好代码成功打印出了目标信息,也对相关代码有了更好的理解,果然还是Practice makes perfects.

参考资料:

嵩天. Python网络爬虫与信息提取[EB/OL]./course/BIT-1001870001.

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。