Python网络爬虫与信息提取(三):网络爬虫之提取(Beautifulsoup bs4)
Beautifulsoup库简介
Beautifulsoup,又叫美丽汤,是一个优秀的python第三方库,能够对html,xml进行解析,并且提取其中的相关信息。
Beautifulsoup的使用原理是他能够吧任何你给他的文档当做一锅汤,然后给你煲制这锅汤
import requests r = requests.get('http://python123.io/ws/demo.html') demo = r.text from bs4 import BeautifulSoup #from bs4导入了 一个类叫BeautifulSoup soup = BeautifulSoup(demo,'html.parser') #把demo的页面熬成一个beautifulsoup能够理解的汤 print(soup.prettify()) #还要给出解析demo的解释器
BeautifulSoup库的基本元素
无论哪种解析器,它都是可以有效解析xml和html文档的
包含a标签的上一层标签
基于bs4库的html内容遍历方法
#标签树的上行遍历 import requests r = requests.get('http://python123.io/ws/demo.html') r.text demo = r.text from bs4 import BeautifulSoup soup = BeautifulSoup(demo, 'html.parser') for parent in soup.a.parents: if parent is None: print(parent) else: print(parent.name)
所有平行遍历必须是在同一个父亲节点下
基于bs4的HTML格式输出
bs4库的prettiffy()方法——给所有标签后面都添加换行符
bs4库将任何读入的html文件或字符串都转换成了UTF-8编码(python3 默认支持编码也是UTF-8)
信息标记的三种形式—XML、JSON、YAML
信息标记的三种形式—XML、JSON、YAML_hxxjxw的博客-CSDN博客
信息提取的一般方法
实例
import requests r = requests.get('http://python123.io/ws/demo.html') demo = r.text from bs4 import BeautifulSoup soup = BeautifulSoup(demo, 'html.parser') for link in soup.find_all('a'): print(link.get('href'))
基于bs4库的HTML内容查找方法
由于find_all函数非常常用,在buautifulsoup库中还有一种简写形式
实例:中国大学排名爬虫
request-bs4是无法获取由js等脚本语言动态生成的信息的,只能提取的信息是写在html页面的代码中才行
输出的format
import requests from bs4 import BeautifulSoup import bs4 def getHTMLText(url): # 输入需要获取的url的信息,输出是url的内容 try: r = requests.get(url, timeout=30) r.raise_for_status() r.encoding = r.apparent_encoding return r.text except: return "" # 整个程序的核心部分 # 从html文件中首先找到tbody标签,获取所有大学的相关信息 # 然后在tbody标签中解析tr标签,获得每一个大学的信息 # 再把tr标签中的td标签找到,把每个大学的相关的数据参数写道对应的ulist列表中 def fillUnivList(ulist, html): # 将html页面放入ulist列表中 soup = BeautifulSoup(html, 'html.parser') for tr in soup.find('tbody').children: if isinstance(tr, bs4.element.Tag): # 它的儿子中可能会出现字符串类型,而所有大学信息都是封装在标签中是标签类型,所以过滤一下 tds = tr('td') # 对tr标签中的td做查询 ulist.append([tds[0].string, tds[1].string, tds[3].string]) def printUnivList(ulist, num): # 将列表中的元素打印出来 print('{:^10}\t{:^6}\t{:^10}'.format('排名', '学校名称', '总分')) for i in range(num): u = ulist[i] print('{:^10}\t{:^6}\t{:^10}'.format(u[0], u[1], u[2])) def main(): # 主函数 uinfo = [] url = 'http://www.zuihaodaxue.com/zuihaodaxuepaiming2018.html' html = getHTMLText(url) fillUnivList(uinfo, html) printUnivList(uinfo, 20) main()
解决中文对齐问题
当中文字符宽度不够时,系统默认采用西文字符填充导致不对齐
import requests from bs4 import BeautifulSoup import bs4 def getHTMLText(url): # 输入需要获取的url的信息,输出是url的内容 try: r = requests.get(url, timeout=30) r.raise_for_status() r.encoding = r.apparent_encoding return r.text except: return "" # 整个程序的核心部分 # 从html文件中首先找到tbody标签,获取所有大学的相关信息 # 然后在tbody标签中解析tr标签,获得每一个大学的信息 # 再把tr标签中的td标签找到,把每个大学的相关的数据参数写道对应的ulist列表中 def fillUnivList(ulist, html): # 将html页面放入ulist列表中 soup = BeautifulSoup(html, 'html.parser') for tr in soup.find('tbody').children: if isinstance(tr, bs4.element.Tag): # 它的儿子中可能会出现字符串类型,而所有大学信息都是封装在标签中是标签类型,所以过滤一下 tds = tr('td') # 对tr标签中的td做查询 ulist.append([tds[0].string, tds[1].string, tds[3].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/zuihaodaxuepaiming2018.html' html = getHTMLText(url) fillUnivList(uinfo, html) printUnivList(uinfo, 20) main()