博主本学期学校有开设python课程,使用教材为嵩天老师编写的《Python语言程序设计实例》。
期末作业是从P279页任意选题编写python程序,于是博主选择了中国大学排名爬虫这个,原因是之前书里有示例,心想着嫖书上代码不是爽歪歪(事实证明白嫖果然是不好滴)
然后惨案就开始了。。。。。。。
书中给出的源码爬不出来了(废话要能爬出来我写这个干嘛)
这点场面当然难不住身为学————渣的我,于是我就祭出了神器CSND(csdn请打钱谢谢)
在我尝试了数个博客教程,而无一例外全部失败后。
我:
看来我只能自己莽了。
分析书中源码,可总结为三步:
步骤1:从网络上获取大学排名网页内容 getHTMLText()
步骤2:提取网页内容中信息到合适的数据结构 fillUnivList()
步骤3:利用数据结构展示并输出结果 printUnivList()
感觉没啥问题啊,咋就爬不出来呢。
值得说明的是:教材给的url已失效,现在使用的是这个:
【软科排名】2021年最新软科中国大学排名|中国最好大学排名 (shanghairanking.cn)
又去查了很多相关知识,已经数次尝试后————————
'NoneType' object has no attribute 'children'
IndexError: list index out of range
(教材和csdn中大量教程报错无外乎这两个,有兴趣的可以自己去搜索尝试一下)
百思不得其解(主要还是菜)
爬取都爬取不到,最后在分析了下爬取的源代码之后,发现源代码中并没有需要的dom
但是在浏览器检查元素的时候又是有的,这就让我很难过了
无奈请教大佬
发现问题根源是因为普通方法获取的只是服务器端本地的静态资源,也就是第一手资源
而浏览器检查元素的资源是经过js渲染后的代码
明确方向后就好办多啦
教材给的案例是分析纯HTML文本,而我们现在需要获取js网页渲染后的源码,下面我们顺着这个思路去改。
方法一:利用selenium模块获取渲染后的源码,剩下都步骤就和上面一样了。
方法二:找一个纯HTML文本的相关url分析。
方法三:直接读JSON(这样几行代码就可以搞定,剩下的就是操作列表和字典)
法二很简单,重点记录以下法一和法三。
法一
需要安装selenium模块,可以参考: selenium在ananconda环境下的安装与浏览器配置_molaum的博客-CSDN博客
代码:
import requests
from bs4 import BeautifulSoup
import bs4
from selenium import webdriver
allUniv = []
def get_newHtMLText(url): #获取网页信息
dr = webdriver.Chrome()
dr.get(url)
source = dr.page_source
return source
def fillUnivList(soup): #数据清洗
data = soup.find_all('tr')
for tr in data:
ltd = tr.find_all('td')
if len(ltd)==0:
continue
singleUniv = []
for td in ltd:
singleUniv.append(td.text)
allUniv.append(singleUniv)
def printUnivList(num): #输出
print("{:^10}{:^25}{:^20}{:^20}{:^20}".format("排名", "学校名称", "省市", "类型", "总分"))
for i in range(num):
u = allUniv[i]
u = [x.strip() for x in u]
print("{:^10}{:^10}{:^20}{:^20}{:^20}".format(u[0], u[1], u[2], u[3], u[4]))
def main():
url = 'https://www.shanghairanking.cn/rankings/bcur/202111'
html = get_newHtMLText(url)
soup = BeautifulSoup(html, "html.parser")
fillUnivList(soup)
printUnivList(30)
main()
运行结果:
法三
分析json文本的可以看看这篇: python爬虫 2021中国大学排名定向爬虫_sereasuesue的博客-CSDN博客
代码:
import requests
import json
url = 'https://www.shanghairanking.cn/api/pub/v1/bcur?bcur_type=11&year=2021'
r = requests.get(url, timeout=30)
json_data = json.loads(r.text)
a = json_data['data']['rankings']
for i in a:
print('第 '+ i['ranking'] + ' 名 '+ i['univNameCn'])
运行结果:
🆗,问题解决!
——————————————————————————————————————————
总结:
在一个没有技术难点的作业(就教材所给来看是没有难度的,但是教材内容的案列已经很久了,很多网址已更新或者网络框架已经更新)实现上花了好多时间,给我最大的反思是:方向比努力重要。
在错误的方向上浪费时间;而不注重在方向判断上努力;这是战略层面的懒惰。
结案。
累了,这个月都不想再碰爬虫。
欢迎大家在评论区讨论建议鸭(估计没人看,哼,我自己看)
最后感谢给我提供帮助和建议的朋友们,没有你们就没有这篇文章的诞生。(^-^)