python & bs4 基础

python & bs4

如果基于正则表达式来爬取网页,真的是太麻烦,而且正则要学得好,还真不容易。通过 bs4 select 或者 find 返回soup对象,可以很方便地提取出HTML或XML标签中的内容,简直不能更方便

举例:

1
2
3
4
5
req = urllib2.Request(target_url, headers = _headers)
myPage = urllib2.urlopen(req).read().decode(self.encoding)
soup = BeautifulSoup(myPage,'lxml')

dom_tag_a = soup.select('div[class*="right_wrap"] > div[class*="content"] > div[class*="phref"] > a')

###安装 BeautifulSoup & html5lib & lxml

pip install beautifulsoup4
pip install html5lib
pip install lxml

easy_install 同理

bs升级到4后,实例化时需要明确指定文档解析器。lxml 和 html5lib 都属于bs4的第三方文档解析器。

  • python标准解析库html.parser,执行速度适中,容错强
  • lxml HTML解析库lxml,速度快,容错强,需要安装c语言库
  • lxml XML解析器["lxml","xml"],速度快,唯一支持xml解析
  • html5lib 最好的容错,以浏览器方式解析文档;速度慢
1
2
3
4
5
6
7
8
#python内置解析库
BeautifulSoup(markup,'htmp.parser')
#lxml 解析 html
BeautifulSoup(markup,'lxml')
#xml 解析
BeautifulSoup(markup,['lxml','xml'])
#最好的容错,最慢的速度
BeautifulSoup(markup,'html5lib')

基础用法:select

select() 是从BeautifulSoup对象中索取网页元素,并用css选择器寻找元素,不同的选择器模式可以进行组合,应付复杂配对

# 搜索id=author 的p标签
soup.select('p #author')

常用CSS 选择器,更多CSS选择器参看w3cschool的文档:

  • soup.select(‘div’)
  • soup.select(‘#author’),ID搜索
  • soup.select(‘.notice’)
  • soup.select(‘div span’) ,div内所有span 元素
  • soup.select(‘div > span’) ,div内所有span 元素,必须完全符合路径才能搜索到
  • soup.select(‘input[name]’),属性存在,搜索存在name 的input 元素
  • soup.select(‘input[type=”button”]’),属性匹配,搜索type=button的input元素
  • soup.select(‘[class*=clearfix]’),类名搜索,查找class包含了clearfix 的元素
  • soup.select(‘#link ~ .clearfix’),兄弟搜索,找到id为link标签的所有class=clearfix的兄弟标签
  • soup.select(‘n nth-of-type(3)’),序列搜索,选择第三个p标签 3 替换成 odd 表示奇数p标签 even ,n,3n 的倍数p标签 ,3n+1 表示 第 4,10 ..个元素

基础用法:find 和 find_all

find_all(name,attrs,recursive,text,**kwargs)
find(name,attrs,recursive,text,**kwargs)

find 返回的是匹配的第一个结果,find_all 返回的是所有的匹配结果

参数的含义

name:name参数可以查找所有名字为name的tag,name值可以有很多:标签、字符串、RE、甚至是函数方法等等

eg 1:标签 tag name

#查找所有b标签
soup.find_all('b')

eg 2:正则表达式

#查找所有以b开头的标签
soup.find_all(re.compile('^b'))

eg 3: 传一个list 或者 dictionary。

# 查找所有的<title> 和 <p>标签,后一种方法快一些
soup.find_all(['title','p'])
soup.find_all({'title':True,'p':True})

eg 4: 传一个True值,这样可以匹配每个tag的name,也就是匹配每个tag

soup.find_all(True)

eg 5: 传入 定义的一个函数

def has_class_but_no_id(tag):
    return tag.has_attr('class') and not tag.has_attr('id')
#将该函数 传入,将得到所有有class属性无id的标签
soup.find_all(has_class_but_no_id)

keywords: keywords在方法参数中并没有明示,但是能帮我们筛选tag的属性

soup.find_all('p',align='center')

attrs: attrs是一个字典,可以是用attrs去匹配那些名字为Python保留字的属性,例如class,for,name,recursive,limit等等

soup.find_all(attrs={'id':re.compile("para$")})

text text 参数用于搜索文档中的字符串内容。与name参数一样是可选参数,text参数接受字符串,正则表达式,列表,True

# 搜索文档中含有“one”的字符串
soup.find_all(text='one')

recursive: recuresive是一个boolean 参数,表示是否检索当前tag的所有子孙节点


Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×