beautifulSoup模块 (专门用于解析XML文档)
安装:pip3 install bs4
安装解析器:
# lxml,根据操作系统不同,可以选择下列方法来安装lxml: (推荐使用,解析快) $ apt-get install Python-lxml $ easy_install lxml $ pip3 install lxml
# html5lib,html5lib的解析方式与浏览器相同,可以选择下列方法来安装html5lib:(最稳定) $ apt-get install Python-html5lib $ easy_install html5lib $ pip3 install html5lib # lxml HTML 解析器 # lxml XML 解析器
基本使用
import requests from bs4 import BeautifulSoup
response=requests.get("https://www.baidu.com") soup = BeautifulSoup(response.text,"lxml") # 开始解析,生成解析对象,第一个参数html文档,第二个参数为解析器 res=soup.prettify() #处理好缩进,结构化显示
查找元素(遍历整个文档)
爬取一个标签的名字,属性,文本
# 一个标签分为 标签名,属性,文本 soup = BeautifulSoup("xx.html","lxml") tag = soup.body # 查找body标签内的所有内容 tag.name # 爬取标签的名字 tag.attrs # 爬取标签的属性值 tag.text # 爬取标签的文本
点语法查找元素
# 点语法查找第一个标签的 tag.a # 查找第一个a标签 tag.a.attrs.get("href") # 查找a标签的href属性值 tag.a.text # 查找a标签的文本信息
嵌套查找
tag.a.p.text # 查找的是a标签里的p标签的文本
获取某一个标签里的所有子标签,不能取出子标签里的子标签
tag.a.contents # 查找a标签里的所有子标签,返回一个列表 tag.a.children # 查找的是a标签里的所有子标签,返回一个迭代器 for i in tag.a.children: print(i.name) # 查找a标签的所有子标签的名字 tag.p.descendants # 获取子孙节点,p下所有的标签都会选择出来(能取出子标签里的子标签) # 会把所有子标签的文本,空格拆成一个节点
获取父标签
tag.p.parent # 查找p标签的上一级 tag.p.parents # 查找p标签的所有上级(父级,父级的父级,所有父级),返回一个迭代器 eg: list(tag.p.parents)
获取兄弟标签,文本也被当作一个节点
tag.a.next_sibling # 获取a标签的下一个标签 tag.a.next_sibling.next_sibling # 获取a标签的下一个兄弟标签的下一个兄弟标签 tag.a.next_siblings # 获取a标签所有下面的兄弟标签 tag.a.previous_sibling # 获取a标签的上一个兄弟标签 tag.a.previous_siblings # 获取a标签的所有上面兄弟标签
删除文档树
去除指定标签,PageElement.extract() 方法将当前tag移除文档树,并作为方法结果返回:
from bs4 import BeautifulSoup # 去除属性ul [s.extract() for s in soup("ul")] # 去除属性svg [s.extract() for s in soup("svg")] # 去除属性script [s.extract() for s in soup("script")]
去除注释,PageElement.extract() 方法将当前tag移除文档树,并作为方法结果返回:
from bs4 import BeautifulSoup, Comment # 去除注释 comments = soup.findAll(text=lambda text: isinstance(text, Comment)) [comment.extract() for comment in comments]
使用decompose()——方法将当前节点移除文档树并完全销毁:
markup = '<a href="http://example.com/">I linked to <i>example.com</i></a>' soup = BeautifulSoup(markup) a_tag = soup.a soup.i.decompose() a_tag # <a href="http://example.com/">I linked to</a>
过滤查找
简单使用
from bs4 import BeautifulSoup response=requests.get("https://www.baidu.com") soup = BeautifulSoup(response.text,"lxml") # 开始解析,生成解析对象,第一个参数html文档,第二个参数为解析器
soup.find_all("a") # 查找所有的a标签(包含a标签里的所有子标签)
标签名过滤
soup.find_all("a") # 查找所有的a标签(包含a标签里的所有子标签) soup.find_all(["a","p"]) # 查找所有的a标签,p标签
标签属性过滤
soup.find_all("a",attrs={"id":"link1"}) # 查找id为link1的所有a标签 soup.find_all(name="a",attrs={"id":"link1"}) # 查找id为link1的所有a标签
# class属性过滤 soup.find_all(name="a",class_="sister brother") # 多类名过滤,类名必须完全一致,才能过滤 # 特殊符号属性过滤,放在attrs参数里 soup.find_all(name="a",attrs={"data-a":"sister"}
特殊文本过滤,文本必须完全一致
soup.find_all(text="xxxx") # 过滤出来是文本 soup.find_all(name="ssss",text="xxxx") # 过滤出来的文本是xxxx的标签名为ssss的标签
正则匹配过滤
import re
c = re.compile("a") print(soup.find_all(name=c)) # 过滤出标签名带有a的标签
True 过滤标签
soup.find_all(name=True) # 查找所有的标签 soup.find_all(id=True) # 查找所有带有id属性的标签
函数名方法过滤
def myFilter(tag): # 必须只能有一个参数 参数表示要过滤的标签 return tag.name == "a" and tag.text != "Elsie" and tag.has_attr("id") soup.find_all(myFilter,limit=1) # 查找标签名为a且文本为Elsie且有一个id属性
选择器过滤
soup.select("a") # 查早所有的a标签 soup.select(".sister") # 查找所有类名为sister的标签,类选择器 soup.select("#bb") # 查找所有id为bb的标签名,id选择器 soup.select("#b #c") # 查找所有id为b下的id为c的标签,后代选择器 soup.select("#b>.c") # 查找所有id为bb下的类名为c的标签,子代选择器