下面是一段定向爬虫代码,用于爬取中国大学排名,并打印前二十个大学的信息
代码来自北京理工大学的在线课程《Python网络爬虫与信息提取》
import requests
from bs4 import BeautifulSoup
import bs4
def getHTMLText(url):
try:
r = requests.get(url, timeout = 30)
r.raise_for_status
r.encoding = r.apparent_encoding
return r.text
except:
return ""
def fillUnivList(ulist, html):
soup = BeautifulSoup(html, "lxml")
for tr in soup.find('tbody').children:
if isinstance(tr, bs4.element.Tag):
tds = tr('td')
ulist.append([tds[0].string, tds[1].string, tds[2].string])
def printUnivList(ulist, num):
tplt = "{0:^10}\t{1:{3}^10}\t{2:^10}"
print(tplt.format("排名","学校名称","总分",chr(12288)))
for i in range(num):
u = ulist[i]
print(tplt.format(u[0],u[1],u[2],chr(12288)))
def main():
uinfo = []
url = "http://www.zuihaodaxue.com/zuihaodaxuepaiming2017.html"
html = getHTMLText(url)
fillUnivList(uinfo, html)
printUnivList(uinfo, 20)
main()
这段代码包含了四个函数
- getHTMLText()
用于获取HTML源代码内容 - fillUnivList()
用于提取源代码内容中有用的部分 - printUnivList()
用于将提取到的有用内容打印出来 - main()
主函数,整合以上三个函数,实现目标功能
1.getHTMLText()
def getHTMLText(url):
try:
r = requests.get(url, timeout = 30)
r.raise_for_status
r.encoding = r.apparent_encoding
return r.text
except:
return ""
r = requests.get(url, timeout = 30)
使用requests库的get方法,设定timeout为30秒,得到一个名为r的Response对象
r.raise_for_status
在连接失败时会返回一个异常,此时将直接跳转到except下执行return ""
语句,以此保证代码的稳定性
r.encoding = r.apparent_encoding
一般而言apparent_encoding判断的编码格式更准确,因此本句将r.encoding赋值r.apparent_encoding
return r.text
返回url对应网页的内容
2.fillUnivList()
def fillUnivList(ulist, html):
soup = BeautifulSoup(html, "lxml")
for tr in soup.find('tbody').children:
if isinstance(tr, bs4.element.Tag):
tds = tr('td')
ulist.append([tds[0].string, tds[1].string, tds[2].string])
soup = BeautifulSoup(html, "lxml")
使用lxml解析器解析html内容,此处也可以使用html.parser
<tbody class="hidden_zhpm" style="text-align:center;">
<tr class="alt"><td>1<td><div align="left">清华大学</div></td><td>北京</td><td>94.0 </td><td class="hidden-xs need-hidden indicator5">100.0
查看网页源代码,我们发现大学信息在tbody标签下,每个tr标签对应一所大学,tr标签下的td标签则对应大学的各项信息
因此我们在解析出的内容soup中找到tbody标签的各个子节点即tr,由于一些文本内容也属于节点,我们用if isinstance(tr, bs4.element.Tag)
语句对tr的类型进行判断,确保tr是标签
tds = tr('td')
将在tr下找到所有td标签内容并以列表形式存入tds
ulist.append([tds[0].string, tds[1].string, tds[2].string])
将tds的前三个内容存入ulist
注意此处的ulist是一个多维列表,其包含数个含有三个元素的列表
3.printUnivList()
def printUnivList(ulist, num):
tplt = "{0:^10}\t{1:{3}^10}\t{2:^10}"
print(tplt.format("排名","学校名称","总分",chr(12288)))
for i in range(num):
u = ulist[i]
print(tplt.format(u[0],u[1],u[2],chr(12288)))
print(tplt.format("排名","学校名称","总分",chr(12288)))
格式化打印表头,chr(12288)是中文空格,用于填补空缺,防止由于中英文占位不同引起格式混乱
做循环print(tplt.format(u[0],u[1],u[2],chr(12288)))
打印各个学校的信息
4.main()
def main():
uinfo = []
url = "http://www.zuihaodaxue.com/zuihaodaxuepaiming2017.html"
html = getHTMLText(url)
fillUnivList(uinfo, html)
printUnivList(uinfo, 20)
html = getHTMLText(url)
使用getHTMLText()方法获取url的网页源码内容,存入html变量
fillUnivList(uinfo, html)
使用fillUnivList()方法填充uinfo列表
printUnivList(uinfo, 20)
打印前二十个大学的信息