“爬取大学排名”实例
知识及技巧储备
获取源码:选中右键检查-选中右键复制selector
nth-of-type(1)和nth-of-children(1):nth-of-type(1) 选择器指定的是标签
确定标签从属关系:选中右键检查-上移并对比左侧原网页
r.raise_for_status():只检查响应状态码,不打印,通过即继续下一代码,不通过即返回空字符串return""
if isinstance(tr, bs4.element.Tag):isinstance函数是python自带的函数,用于判断对象类型,用其检验对象是否为bs4对象时,需引用import bs4
soup.find('tbody')等价于soup.tbody:都只返回找到的第一个tbody,这是一个bs4对象可以直接调用bs4函数
soup.find_all('tbody'):返回的是一个列表,需对其中每一个对象进行处理,如for tbody in soup.find_all('tbody'),同理.select()返回的也是一个列表.
[1] 第6、7条总结来说soup.find('tbody') 和 soup.tbody 只返回第一个 <tbody>。 soup.find_all('tbody') 和 soup('tbody') 返回所有 <tbody> 标签的列表。 soup.select('tbody') 也返回所有 <tbody> 标签的列表,且支持更复杂的 CSS 选择器语法。zip()函数:将多个可迭代对象(如列表)中的元素逐一配对聚合成一个元组的迭代器
.strip() 方法:移除字符串两端的空白字符
中文字符对齐问题:format方法中{1:{3}^10} 是一个嵌套的格式化说明符, Python 3.6 以上版本支持。{3}: 表示填充字符来自于 format() 方法中的第四个参数(索引为 3)。
find方法爬取
import requests
from bs4 import BeautifulSoup
import bs4
#获取url信息,输出html格式的内容
def getHTMLText(url):
try: #try except 结构规定这个函数的结构框架
r = requests.get(url, timeout=30)
r.raise_for_status() #产生异常信息
r.encoding = r.apparent_encoding
return r.text
except:
return "" #如果出现错误,返回空字符串
#将url内容放在大学列表中
def fillUnivList(ulist,html):
soup = BeautifulSoup(html, "html.parser")
#原网页界面选中清华大学右键"检查"-源码中对应span标签-源码中由span上移逐渐对应原界面中整个清华大学的信息-找到tr标签
#找到层级关系 tbody-tr-td
#找到tbody获取所有大学信息-再解析tr标签获取每个大学信息-解析td标签获取每个参数信息
for tbody in soup.find_all('tbody'):
#isinstance函数是bs4库中的函数,需引用该库
for tr in tbody.find_all("tr"):
if isinstance(tr, bs4.element.Tag):
tds = tr.find_all('td')
span = tds[1].find_all('div')[0]
span = span.find_all('div')[2]
span = span.find_all('div')[0]
span = span.find_all('div')[0]
span = span.find_all('span')[0]
ulist.append([tds[0].string,span.string, tds[4].string])
#将列表的内容规范格式打出来,打印num个学校
def printUnivList(ulist,num):
tplt = "{0:^12}\t{1:{3}^28}\t{2:^12}"
print(tplt.format("排名", "学校名称", "总分", chr(12288)))
for i in range(num):
u = ulist[i]
print(tplt.format(u[0].strip(), u[1].strip(), u[2].strip(), chr(12288)))
def main():
uinfo = [] #收集大学信息的列表
url = "https://www.shanghairanking.cn/rankings/bcur/2016"
html = getHTMLText(url)
fillUnivList(uinfo, html)
printUnivList(uinfo,20)
main()
select方法爬取
import requests
from bs4 import BeautifulSoup
import bs4
#获取url信息,输出html格式的内容
def getHTMLText(url):
try: #try except 结构规定这个函数的结构框架
r = requests.get(url, timeout=30)
r.raise_for_status() #产生异常信息
r.encoding = r.apparent_encoding
return r.text
except:
return "" #如果出现错误,返回空字符串
#将url内容放在大学列表中
def fillUnivList(uinfo,html):
soup = BeautifulSoup(html, "html.parser")
#原网页界面选中清华大学右键"检查"-源码中对应span标签-源码中由span上移逐渐对应原界面中整个清华大学的信息-找到tr标签
#找到层级关系 tbody-tr-td
#找到tbody获取所有大学信息-再解析tr标签获取每个大学信息-解析td标签获取每个参数信息
for tr in soup.tbody.find_all('tr',recursive=False):
#isinstance函数是bs4库中的函数,需引用该库
if isinstance(tr, bs4.element.Tag):
ranks = tr.select("td:nth-of-type(1) > div")
names = tr.select("td.align-left > div > div.univname > div:nth-of-type(1) > div > div > span")
scores = tr.select("td:nth-of-type(5)")
for rank, name, score in zip(ranks, names, scores):
data={'rank':rank.get_text(), 'name':name.get_text(), 'score':score.get_text()}
uinfo.append(data)
#将列表的内容规范格式打出来,打印num个学校
def printUnivList(uinfo,num):
print("{0:^10}\t{1:{3}^10}\t{2:^10}".format("排名", "学校名称", "总分", chr(12288))+'\n')
num = min(num, len(uinfo))
for i in range(num):
u = uinfo[i]
print("{0:^10}\t{1:{3}^10}\t{2:^10}".format(u['rank'].strip(), u['name'].strip(), u['score'].strip(), chr(12288))+'\n')
print("Suc"+str(num))
def main():
uinfo = [] #收集大学信息的列表
url = "https://www.shanghairanking.cn/rankings/bcur/2016"
html = getHTMLText(url)
fillUnivList(uinfo, html)
printUnivList(uinfo,20)
main()