本文初衷仅作为学习交流,因为我在刚开始学的时候什么东西都爬不出来,艰苦摸索过一段时间,希望这篇文章可以给爬虫入门的小伙伴一点帮助
看见有些小伙伴问我为什么爬取不到信息,是因为我这篇博客是2020年写的,如今最好大学网也改版啦,想要爬取信息就需要重新解析网页了。
本文是写于我刚学习python爬虫的时候,自身对爬虫的理解也不太深,所以对博客爬取具体详情也没有细说。源于学习mooc上嵩天老师的爬取大学排名,练习网址为最好大学网
一、确定目标
希望写出一个小爬虫获取信息,首先需要确定的是自己希望爬取的内容在上面地方。进入网站可看见如下页面
我确定的目标是中国大学排名,点击进入查看
二、解析网页
已经进入了目标页面,按f12键查看网页源码,具体如下。
前期的准备工作就已经完成了,接下来我们需要先尝试的爬一下,测试网页有什么反爬机制,代码如下。
import requests
def getHTMLText(url):
try:
r = requests.get(url,timeout=30)
r.raise_for_status()#如果状态不是200,引发HTTPError异常
r.encoding = r.apparent_encoding
return r.text
except:
return"产生异常"
if __name__ == "__main__":
url = r'https://www.shanghairanking.cn/rankings/bcur/2021'
print(getHTMLText(url))
程序输出结果如下,目测网站对初学者非常友好,请求头都不限制。
找到存放大学排名榜的标签。
对应标签是在tbody标签,所以直接定位到tbody
此处每一个tr标签装的就是一个大学的信息,结构比较清晰,具体取第一个tr标签看看。
继续展开可以看见
- tr.contents[0] --------->排名
- tr.contents[1] --------->大学名称以及相关tag
- tr.contents[2] --------->所在省市
- tr.contents[3] --------->大学类型
- tr.contents[4] --------->总分
- tr.contents[5] --------->办学层次
通过tbody查找每个子节点分别获取排名、大学名称、分数
#print(tr.contents[0].div.string)#排名
#print(tr.contents[1].find("a",class_="name-cn").string)
#print(tr.contents[4].string) # 总分
所用语法细则可看bs库的使用文档,其已经比较详细。
直接保存到列表中即可,我目前只是稍微尝试,具体想要爬取更多内容可以自行拓展
三、完整源码
import requests
from bs4 import BeautifulSoup
import pandas as pd
#爬取网页源码
def getHTMLText(url):
try:
r = requests.get(url, timeout = 30)
r.raise_for_status()#如果状态不是200,引发HTTPError异常
r.encoding = r.apparent_encoding
return r.text
except:
return"产生异常"
#解析网页并获取信息
def getInfo(text,data):
name = ''
rank = ''
score = ''
soup = BeautifulSoup(text, 'lxml')
#print(soup.tbody.prettify())
for tr in soup.tbody.children:#遍历每个tr标签
#print(tr.contents[0].div.string)#排名
rank = int(tr.contents[0].div.string)
#print(tr.contents[1].find("a",class_="name-cn").string) # 大学名称
name = tr.contents[1].find("a",class_="name-cn").string
#print(tr.contents[4].string) # 总分
score = float(tr.contents[4].string)
data.append([rank,name,score])
#保存信息
def saveInfo(info):
df = pd.DataFrame(info)
df.to_excel('中国大学排名.xlsx', header=False, index=False)
if __name__ == "__main__":
url = r'https://www.shanghairanking.cn/rankings/bcur/2021'
data = [['大学名称','排名','总分']]
HTMLText = getHTMLText(url)#获取
getInfo(HTMLText,data)#解析
saveInfo(data)#保存
print("爬取成功!")