BeautifulSoup与urlopen结合来进行爬虫
先讲一下BeautifulSoup的安装,用指令:pip3 install BeautifulSoup4(python2的话,直接pip)
下面是一段简单的爬虫示例,从代码开始梳理
from bs4 import BeautifulSoup #python爬虫常用工具 pip3 install BeautifulSoup4 from urllib.request import urlopen url='http://image.baidu.com/search/index?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=-1&st=-1&fm=result&fr=&sf=1&fmq=1566467638187_R&pv=&ic=&nc=1&z=&hd=&latest=©right=&se=1&showtab=0&fb=0&width=&height=&face=0&istype=2&ie=utf-8&hs=2&sid=&word=%E7%99%BE%E5%BA%A6%E7%99%BE%E7%A7%91%E5%8A%A8%E7%89%A9' html=urlopen(url).read().decode('utf-8') soup=BeautifulSoup(html,features='lxml') #首次运行是要pip install lxml 也就是网页解析器 for li in soup.find_all('li'): if li.get('class')=='imgitem': print(li.get('data-objurl'))
首先要引进两个模块,urlopen是用来解析网址的.代码示例中,url中放的是要爬虫数据的网页地址,然后把地址传到urlopen(url).read().decode(‘utf-8’)中,得到的是整个网页的html代码(也就是说html里是整个页面的代码)
url='http://image.baidu.com/search/index?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=-1&st=-1&fm=result&fr=&sf=1&fmq=1566467638187_R&pv=&ic=&nc=1&z=&hd=&latest=©right=&se=1&showtab=0&fb=0&width=&height=&face=0&istype=2&ie=utf-8&hs=2&sid=&word=%E7%99%BE%E5%BA%A6%E7%99%BE%E7%A7%91%E5%8A%A8%E7%89%A9' html=urlopen(url).read().decode('utf-8')
得到整个页面的代码之后再将整个代码喂到BeautifulSoup对象中,features是指的是页面解析器,注意,lxml要提前进行安装,pip install lxml,但如果用html.parser则不用提前安装解析器也就是features=‘html.parser’
soup=BeautifulSoup(html,features='lxml')
得到一个BeautifulSoup对象后,一般通过BeautifulSoup类的基本元素来提取html中的内容
接下来我们讲解一下BeautifulSoup具体怎么使用?
①首先是获取整个标签:
print(soup.title) # 获取html的title标签的信息 print(soup.a) # 获取html的a标签的信息(soup.a默认获取第一个a标签,想获取全部的就用soup.find_all('a'),下面会详细介绍 print(soup.a.name) # 获取a标签的名字 print(soup.a.parent.name) # a标签的父标签(上一级标签)的名字 print(soup.a.parent.parent.name) # a标签的父标签的父标签的名字
②获取标签属性里的值,有两种方式,一种是soup.a.attrs[‘class’],另一种是soup.a.get(‘class’),两者的差别在于,如果a标签没有classs属性的时候,用soup.a.attrs[‘class’]会报错,用soup.a.get(‘class’)不会报错,如果标签a有class属性的时候,两者的效果一样.
————————————————
print('a标签类型是:', type(soup.a)) # 查看a标签的类型 print('第一个a标签的属性是:', soup.a.attrs) # 获取a标签的所有属性(注意到格式是字典) print('a标签属性的类型是:', type(soup.a.attrs)) # 查看a标签属性的类型 print('a标签的class属性是:', soup.a.attrs['class']) # 因为是字典,通过字典的方式获取a标签的class属性,区分soup.a.get('class') print('a标签的href属性是:', soup.a.attrs['href']) # 同样,通过字典的方式获取a标签的href属性
③获取标签的非属性字符串信息,表示尖括号之间的那部分字符串,有两种方式soup.a.string和soup.a.text
print('第一个a标签的内容是:', soup.a.string) # a标签的非属性字符串信息,表示尖括号之间的那部分字符串 print('a标签的非属性字符串的类型是:', type(soup.a.string)) # 查看标签string字符串的类型 print('第一个p标签的内容是:', soup.p.string) # p标签的字符串信息(注意p标签中还有个b标签,但是打印string时并未打印b标签,说明string类型是可跨越多个标签层次)
介绍一下find_all()方法(不管标签在第几层,都是一视同仁,和页面结构没有关系):
常用通过find_all()方法来查找整个页面上某个标签元素:<>.find_all(name, attrs, recursive, string, **kwargs) ,返回一个列表类型,形如[1,2,3,4]来存储查找的结果,也就是一个标签是一个独立元素
• name:对标签名称的检索字符串
• attrs:对标签属性值的检索字符串,可标注属性检索
• recursive:是否对子孙全部检索,默认True
• string:<>…</>中字符串区域的检索字符串
————————————————
1种
print('所有a标签的内容:', soup.find_all('a')) # 使用find_all()方法通过标签名称查找a标签,返回的是一个列表类型 print('a标签和b标签的内容:', soup.find_all(['a', 'b'])) # 把a标签和b标签作为一个列表传递,可以一次找到a标签和b标签
2种
for t in soup.find_all('a'): # for循环遍历所有a标签,并把返回列表中的内容赋给t print('t的值是:', t) # link得到的是标签对象 print('t的类型是:', type(t)) print('a标签中的href属性是:', t.get('href')) # 获取a标签中的url链接
3种
for i in soup.find_all(True): # 如果给出的标签名称是True,则找到所有标签 print('标签名称:', i.name) # 打印标签名称
4种
print('href属性为http..的a标签元素是:', soup.find_all('a', href='http://www.icourse163.org/course/BIT-268001')) # 标注属性检索 或者print('href属性为http..的a标签元素是:', soup.find_all('a', {''href'':'http://www.icourse163.org/course/BIT-268001',''class_'':'title'})) print('class属性为title的标签元素是:', soup.find_all(class_='title')) # 指定属性,查找class属性为title的标签元素,注意因为class是python的关键字,所以这里需要加个下划线'_' print('id属性为link1的标签元素是:', soup.find_all(id='link1')) # 查找id属性为link1的标签元素
BeautifulSoup与requests结合来进行爬虫,BeautifulSoup用法不变,只有页面代码获取的方式由urlopen变成了request
# coding:utf-8 from bs4 import BeautifulSoup import requests url = 'http://python123.io/ws/demo.html' html = requests.get(url).text soup = BeautifulSoup(html, "html.parser") """ html 表示被解析的页面的内容 html.parser表示解析用的解析器 """ print(soup) # 输出响应的html对象 print(soup.prettify()) # 使用prettify()格式化显示输出