从今天开始学爬虫,现在就来分享一个简单完整(具有启发意义)的实例吧。文章结构如下:
1 爬虫问题概述
爬虫即(常用Python)从各个网站/页提取用户感兴趣的各类数据,并做进一步的信息挖掘的程序。爬虫程序实现的步骤主要为:①通过网络链接获取网页内容;②对获取的网页内容进行处理,这俩步骤分别使用requests与beautifulsoup4类库。网络爬虫实则包括:“网络爬虫”与“信息提交”。此外,网站的 “Robots排除协议”可以拒绝爬虫访问。
2 requests库的使用
requests是一个简洁且简单的处理HTTP请求的第三方库。 import requests def getHtmlText(url): try: res=requests.get(url,timeout=15) #超时15秒(url必为:http/https) res.raise_for_status() #如果返回状态不是200,引发异常 res.encoding="utf-8" #使之正常显示中文 return res.text #返回网页内容的字符串形式(res.content()二进制形式) except: '''①ConnectionError异常:DNS查询失败、拒接连接;②HTTPError异常:无效的http响应;③Timeout异常:请求超时;④TooManyRedirects异常:请求超过了设定的最大重定向次数''' return ""
3 beautifulsoup4库的使用
beautifulsoup4是一个解析、处理HTML、XML的第三方库。获取HTML页面内容后,需进一步解析页面格式,提取有用信息。bs4最大的优势是:能根据HTML和XML语法建立解析树,进而高效地解析其中的内容。
bs4采用面向对象思想实现:每一个实例便是一个页面;HTML页面标签(Tag)成为bs4对象的属性(“.”访问);每个Tag也是一个对象(“.”访问)。
层次为:【页面(soup)→Tag标签(head、title、a等)→标签属性(name、attrs、string、contents)→标签属性查找find_all()】
url="http://www.baidu.com"
soup=BeautifulSoup(getHtmlText(url)) #soup对象
print(soup.head) #<head>
print(soup.title) #<title>; type(soup.title):<class 'bs4.element.Tag'>
print(soup.p,soup.body,soup.strings,soup.stripped_strings)#<p>…【远不止这些】
soup_a=soup.a #Tag对象 print("name:",soup_a.name) #Tag名(str) print("attrs:",soup_a.attrs) #此Tag的所有属性(dict) print("string:",soup_a.string) #Tag所夹文本→一般中文(str)【嵌一层,返里层;嵌多层,返None】 print("contents:",soup_a.contents) #此Tag下所有子Tag内容(list)
同一页面可有多个同名标签,而单独“soup.Tag”仅能操控第一个标签,故需用find()或find_all()方法:soup.find_all(name,attrs,recursive,string,limit)→返回列表。①name:标签名、②attrs:Tag属性值(dict)、③recursive:查找层次(仅查找当前Tag下一层False)、④string:关键字检索string属性内容,采用string=开始、⑤limit:返回结果个数(默认全部)。备注:soup.find(name,attrs,recursive,string)→返回字符串(匹配的第一个!)。
tag_a=soup.find_all("a") #所有的构成列表 print(soup.find_all('a',{'href':'http://v.baidu.com'})) #查找特定一个 print(len(soup.find_all('a',{'href':re.compile('baidu.com')}))) #正则表达式“模糊匹配” print(soup.find_all(string=re.compile('百度'))) #['百度一下,你就知道', '关于百度', '使用百度前必读']
4 爬取软科中国大学排名
采用requests爬取网页内容,继而使用beautifulsoup4分析、提取网页中的数据,再储存至二维列表中,最后以用户偏好形式打印出。 import requests from bs4 import BeautifulSoup #但并不是BeautifulSoup库
'''(1)抓取网页内容''' def getHtmlText(url): try: res=requests.get(url,timeout=15) #超时15秒(url必为:http/https) res.raise_for_status() #如果返回状态不是200,则引发异常 res.encoding="utf-8" #使之正常显示中文 return res.text #返回网页内容的字符串形式(res.content()二进制形式) except: '''①ConnectionError异常:DNS查询失败、拒接连接;②HTTPError异常:无效的http响应; ③Timeout异常:请求超时;④TooManyRedirects异常:请求超过了设定的最大重定向次数''' return ""
'''(2)提取网页内容信息''' '''请右键查看网页源码,以决定如何分割字符''' def get_allData(soup): allSchoolData=list() trData=soup.find_all('tr') #页面所有的<tr></tr> for tr in trData: tdData=tr.find_all('td') if len(tdData)==0: #去除非目的<tr> continue oneSchoolData=[] #一个<tr>有多个<td> for td in tdData: oneSchoolData.append(td.string) #某个<td>的string allSchoolData.append(oneSchoolData) return allSchoolData
'''(3)打印结果''' def printResult(data): print("{:^4}{:^10}{:^5}{:^8}{:^10}".format("排名","学校名称","省市","总分","科研规模")) for i in range(len(data)): oneschool=data[i] '''打印什么数据:你得查看具体的网页''' print("{:^4}{:^10}{:^5}{:^8}{:^10}".format(oneschool[0],oneschool[1],oneschool[2],\ oneschool[3],oneschool[6]))
'''主程序''' if __name__=='main': url="http://www.zuihaodaxue.cn/zuihaodaxuepaiming2016.html" soup=BeautifulSoup(getHtmlText(url)) #页面解析对象 printResult(get_allData(soup)) #输出结果
结果如下:
神龙|纯净稳定代理IP免费测试>>>>>>>>天启|企业级代理IP免费测试>>>>>>>>IPIPGO|全球住宅代理IP免费测试