- 功能描述
- 举例说明
- 设计方法
- 程序结构的设计步骤
- 初步完整代码及注释
- 实例优化的代码及步骤
功能说明
输入:大学排名URL链接
输出:大学排名信息的屏幕输出(排名、大学名称、总分)
技术路线:requests + bs4
定向爬虫:仅对输入URL进行爬取,不扩展爬取
确定可行性????
提取返回的页面是否出现在HTML的代码中
举例- 例如最好大学网
http://www.zuihaodaxue.cn/zuihaodaxuepaiming2019.html
查看源代码
查一个例子:Ctrl+F搜索----清华大学
查看网站是否提供robots协议?????
可以手工查看robots协议,发现不存在,则在这里使用爬虫是完全合法可以实现的
希望爬取出来的样例是 排名 学校名称 总分
获取大学排名并且输出大学信息可以分为以下三个步骤
设计方法
- 一、从网页上获取大学排名网页内容
- 二、提取网页内容中信息到合适的数据结构
- 三、利用数据结构展示并 输出结果
程序结构的设计步骤:
- 步骤一、从网络上获取大学排名的网页内容getHTMLText()
- 步骤二、提取网页内容中信息到合适的数据结构 fillUnivList()
- 步骤三、利用数据结构展示并输出结果printUnivList()使用这三个模块是结果更加清晰可读。
完整代码及注释
1 import requests #首先引入requests库和BeautifulSoup库 2 from bs4 import BeautifulSoup 3 import bs4 4 5 #定义三个函数分别对应三个步骤,将三个函数写进来import requests 6 #首先定义三个函数,然后分别定义他们的接口 7 def getHTMLText(url): #输入获取的url信息,输出是url的内容 8 try: 9 r = requests.get(url,timeout = 30)#get获取url信息,并且设置时间是30秒 10 r.raise_for_status() #用raise_for_status产生异常信息 11 r.encoding = r.apparent_encoding #修改编码 12 return r.text #将网页的内容返回给程序的其他部分 13 except: 14 return "" #出现错误,则返回空字符串 15 16 def fillUnivList(ulist,html): #将一个HTML页面中的关键数据添放到list列表中(最核心的部分),要使用BeautifulSoup库 17 soup = BeautifulSoup(html,"html.parser") #用BeautifulSoup类来“煲汤”,采用html的解析器 18 #观察要爬取的网页源代码,发现所有的大学信息被封装在一个表格中,表格的标签叫 tbody, 19 # 在tbody中,每个大学的信息又被封装在一个标签中,这个标签叫tr,即每一个tr标签包含了所有大学的信息 20 #每个tr标签的信息又被td包围 21 #所以要在整个HTML中,首先找到tbody标签,获取所有大学的相关信息 ;然后在tbody标签中解析tr标签,获得每一个大学信息;再把tr标签的td标签找到,把每一个大学的相关参数写到ulist 列表中(用遍历以及查找方法获得) 22 for tr in soup.find('tbody').children: #for语句查找tbody标签,并且将孩子children遍历 23 if isinstance(tr,bs4.element.Tag): #isinstance对函数进行判断,检测tr标签的类型,如果tr不是bs4定义的Tag类型,将过滤掉(并且为了代码可以运行需要引入一个新的类型bs4) 24 tds = tr('td') #将所有的td 标签存为一个列表类型tds , 25 ulist.append([tds[0].string,tds[1].string,tds[3].string]) #在ulist中增加对应的字段,分别是大学排名、大学名称、大学评分 26 '''pass首先解析HTML代码中tbody标签所在的位置,在tbody标签中找到每一所大学对应上午tr 标签,在tr 标签中找到td标签的信息,并把需要的td 标签添加到列表中, 27 ''' 28 '''下面是实现打印大学列表的相关功能 29 需要用到格式化输出《格式化输出的方法》 30 ''' 31 def printUnivList(ulist,num): #将ulist信息打印出来 32 print("{:^10}\t{:^6}\t{:^10}".format("排名","学校名称","总分"))#print 函数实现对表头的打印,下面实现对其他信息的打印 33 for i in range(num): 34 u = ulist [i] 35 '''所有的信息保存在ulist中,想要输出的学校数量由num控制用for循环实现''' 36 print("{:^10}\t{:^6}\t{:^10}".format(u[0],u[1],u[2])) 37 #将第i个学校的信息,作为一个简单的变量u来代替,然后将每一所学校的信息打印出来 38 #注意:为了保证输出的效果,需要使用和表头相一致的支付串表示 39 # print("Suc"+str(num)) #num表示到打印出来的学校的个数 40 # #定义好三个函数之后要写主函数,主函数约定使用main 41 42 43 def main(): 44 uinfo=[] 45 url = "http://www.zuihaodaxue.cn/zuihaodaxuepaiming2019.html" 46 html = getHTMLText(url) 47 fillUnivList(uinfo,html) 48 printUnivList(uinfo,20) #打印大学信息,20个学校(univs) 49 50 mai
同上。
1 import requests 2 from bs4 import BeautifulSoup 3 import bs4 4 5 def getHTMLText(url): 6 try: 7 r = requests.get(url, timeout=30) 8 r.raise_for_status() 9 r.encoding = r.apparent_encoding 10 return r.text 11 except: 12 return "" 13 14 def fillUnivList(ulist, html): 15 soup = BeautifulSoup(html, "html.parser") 16 for tr in soup.find('tbody').children: 17 if isinstance(tr, bs4.element.Tag): 18 tds = tr('td') 19 ulist.append([tds[0].string, tds[1].string, tds[3].string]) 20 21 def printUnivList(ulist, num): 22 print("{:^10}\t{:^6}\t{:^10}".format("排名","学校名称","总分")) 23 for i in range(num): 24 u=ulist[i] 25 print("{:^10}\t{:^6}\t{:^10}".format(u[0],u[1],u[2])) 26 27 def main(): 28 uinfo = [] 29 url = 'http://www.zuihaodaxue.cn/zuihaodaxuepaiming2016.html' 30 html = getHTMLText(url) 31 fillUnivList(uinfo, html) 32 printUnivList(uinfo, 20) # 20 univs 33 main()
结果
实例优化
对齐效果不好,进行改正优化
中文对齐问题的解决:
采用中文字符的空格填充 chr(12288)
1 def printUnivList(ulist, num): 2 tplt = "{0:^10}\t{1:{3}^10}\t{2:^10}" 3 print(tplt.format("排名", "学校名称", "总分", chr(12288))) 4 for i in range(num): 5 u = ulist[i] 6 print(tplt.format(u[0], u[1], u[2], chr(12288)))
改正后
完整代码
1 import requests 2 from bs4 import BeautifulSoup 3 import bs4 4 5 def getHTMLText(url): 6 try: 7 r = requests.get(url, timeout=30) 8 r.raise_for_status() 9 r.encoding = r.apparent_encoding 10 return r.text 11 except: 12 return "" 13 14 def fillUnivList(ulist, html): 15 soup = BeautifulSoup(html, "html.parser") 16 for tr in soup.find('tbody').children: 17 if isinstance(tr, bs4.element.Tag): 18 tds = tr('td') 19 ulist.append([tds[0].string, tds[1].string, tds[3].string]) 20 21 def printUnivList(ulist, num): 22 tplt = "{0:^10}\t{1:{3}^10}\t{2:^10}" 23 print(tplt.format("排名","学校名称","总分",chr(12288))) 24 for i in range(num): 25 u=ulist[i] 26 print(tplt.format(u[0],u[1],u[2],chr(12288))) 27 28 def main(): 29 uinfo = [] 30 url = 'http://www.zuihaodaxue.cn/zuihaodaxuepaiming2016.html' 31 html = getHTMLText(url) 32 fillUnivList(uinfo, html) 33 printUnivList(uinfo, 20) # 20 univs 34 main()