BeautifulSoup4是一个用于从HTML和XML文件中提取数据的Python库。它是一个工具箱,通过解析文档为用户提供他们需要抓取的数据。BeautifulSoup自动将输入文档转换为Unicode编码,并将输出文档转换为utf-8编码。你不需要考虑编码方式,除非文档没有指定编码方式,否则BeautifulSoup无法自动识别编码方式。BeautifulSoup安装使用pip安装BeautifulSoup。pipinstallbs4除了安装解析器外,下表列出了一些常用的解析器。使用BeautifulSoup和四大对象1.创建BeautifulSoup对象frombs4importBeautifulSoupimportrequestsurl="https://www.baidu.com"content=requests.get(url).contentsoup=BeautifulSoup(content)print(soup.prettify())//格式化输出print(soup.get_text())//获取网页的所有文本内容2.BeautifulSoup的四个对象BeautifulSoup将复杂的HTML文档转换成复杂的树结构,每个节点都是一个Python对象,所有对象都可以分为4种类型。标签:HTML中的标签,简单来说就是html标签。NavigableString:简单的说就是标签中的内容。它的类型是一个NavigableString,翻译过来就是一个可遍历的字符串。BeautifulSoup:BeautifulSoup对象表示文档的全部内容。大多数时候,它可以看作是一个Tag对象,是一种特殊的Tag。我们可以分别获取它的类型、名称和属性。Comment:一种特殊类型的NavigableStringObject,实际上输出内容不包含注释符号Tag对象examplefrombs4importBeautifulSoupimportrequestsurl="https://www.baidu.com"content=requests.get(url)。contensoup=BeautifulSoup(content)print(soup.title)print(soup.a)print(soup.p)输出如下图所示,不过貌似这个网页不止一个a标签和p标签,因为是在所有的内容标签中寻找第一个符合要求的,如果想得到所有符合要求的标签,后面会介绍find_all函数。Tag对象中有两个重要的属性,name和attrs。importrequestsurl="https://www.baidu.com"content=requests.get(url).contentsoup=BeautifulSoup(content)print(soup.a.attrs)运行输出如下图所示,及nameoutput是label本身,attrs输出的是一个字典类型。如果我们需要获取标签的某个属性,可以使用字典的一些方法来获取,比如get方法、print(soup.p.get("class"))或者直接使用print(soup.p.get("class"))。p["类"])。NavigableString代码示例:frombs4importBeautifulSoupimportrequestsurl="https://www.baidu.com"content=requests.get(url).contentsoup=BeautifulSoup(content)print(soup.a.string)输出结果如图下图,你可以通过NavigableString类型的string方法轻松获取标签中的内容。BeautifulSoup代码示例:frombs4importBeautifulSoupimportrequestsurl="https://www.baidu.com"content=requests.get(url).contentsoup=BeautifulSoup(content)print(soup.name)print(soup.attrs)outputAs如下所示:评论代码示例:frombs4importBeautifulSouphtmlText='#'soup=BeautifulSoup(htmlText)print(soup.a.string)输出如下,a标签中的内容其实是注释,但是如果用.string的方式输出它的内容,发现它已经把注释符号去掉了,所以这可能会造成不必要的麻烦。文档树遍历直接子节点标签中的content属性可以以列表的形式返回该标签的子节点。通过遍历content返回的列表获取每个子节点。或者直接使用tag的children方法。frombs4importBeautifulSoupimportrequestsurl="https://www.baidu.com"content=requests.get(url).contentsoup=BeautifulSoup(content)print(soup.head.contents)forchildinsoup.head.contents:打印(child)forchildinsoup.head.children:print(child)输出结果如下图所示:所有后代节点标签中的.descendants属性可以递归循环该标签的所有后代节点,类似于children,我们还需要遍历获取内容。frombs4importBeautifulSoupimportrequestsurl="https://www.baidu.com"content=requests.get(url).contentsoup=BeautifulSoup(content)forchildinsoup.descendants:print(child)运行结果输出为如下图所示:节点内容使用.string方法获取内容。如果一个label中没有label,那么.string会返回label中的内容。如果tag中只有一个tag,那么.string也会返回最里面的内容,如果tag中没有内容则返回None。frombs4importBeautifulSoupimportrequestsurl="https://www.baidu.com"content=requests.get(url).contentsoup=BeautifulSoup(content)print(soup.a.string)print(soup.title.string)运行结果输出如下图所示:Multiplecontents使用strippend_strings属性获取多个内容并去除多余的空白字符,需要遍历获取。frombs4importBeautifulSoupimportrequestsurl="https://www.baidu.com"content=requests.get(url).contentsoup=BeautifulSoup(content)forchildinsoup.stripped_strings:print(child)运行结果输出为如下图所示:父节点可以通过元素的.parents属性递归获取元素的所有父节点。frombs4importBeautifulSoupimportrequestsurl="https://www.baidu.com"content=requests.get(url).contentsoup=BeautifulSoup(content,"html.parser")parentObject=soup.head.titleforparentinparentObject.parent:print(parent.name)运行结果输出如下图所示:有一些节点和其他获取的节点一样需要遍历,使用的场景不同。兄弟节点使用.next_siblings或.previous_sibling方法,前后节点使用.next_element或.previous_element方法。搜索文档树find_all(name,attrs,recursive,text,\kwargs)**,find_all()方法用于搜索当前标签的所有标签子节点,判断是否满足过滤条件。传递字符串的最简单过滤器是字符串。在search方法中传入一个字符串参数,beautifulsoup会找到与该字符串完全匹配的内容。下面的例子用于查找文档中的所有a标签frombs4importBeautifulSoupimportrequestsurl="https://www.baidu.com"content=requests.get(url).contentsoup=BeautifulSoup(content,"lxml")print(soup.find_all("a"))运行结果如下图所示:传递一个正则表达式如果传入一个正则表达式作为参数,beautifulsoup会通过正则表达式。在下面的例子中,找到了所有以b开头的标签,也就是说应该找到所有以b开头的标签。frombs4importBeautifulSoupimportrequestsimportreurl="https://www.baidu.com"content=requests.get(url).contentsoup=BeautifulSoup(content,"lxml")fortaginsoup.find_all(re.compile('^b')):print(tag.name)的结果如下图所示:如果传入一个列表参数,BeautifulSoup将返回匹配列表中任意元素的内容。以下代码查找文档中的所有标记和标签。frombs4importBeautifulSoupimportrequestsurl="https://www.baidu.com"content=requests.get(url).contentsoup=BeautifulSoup(content,"lxml")print(soup.find_all(["a","p"]))运行结果如下图所示:传Truetrue匹配任意值,下面代码找到所有标签,但不返回字符串节点。frombs4importBeautifulSoupimportrequestsurl="https://www.baidu.com"content=requests.get(url).contentsoup=BeautifulSoup(content,"lxml")fortaginsoup.find_all(True):print(tag.name)运行结果如下图所示:如果pass函数没有合适的过滤器,那么也可以定义一个函数,该函数只接受一个元素参数,如果该方法返回True,则表示当前元素匹配并找到,如果没有,则返回False。frombs4importBeautifulSoupimportrequestsurl="https://www.baidu.com"content=requests.get(url).contentsoup=BeautifulSoup(content,"lxml")defhas_class_but_no_id(tag):returntag.has_attr('class')andnottag.has_attr('id')print(soup.find_all(has_class_but_no_id))输出结果如下图:keywordparameter注:如果指定名称的参数不是内置参数名,它将搜索Search作为指定名称标签的属性。如果它包含一个名为id的参数,Beautifulsoup将搜索每个标签的“id”值。importrefrombs4importBeautifulSoupimportrequestsurl="https://www.baidu.com"content=requests.get(url).contentsoup=BeautifulSoup(content,"lxml")print(soup.find_all(id='lg'))print(soup.find_all(href=re.compile("hao123")))的结果如下图所示:find(name,attrs,recursive,text,**kwargs),它和find_all()方法是find_all()方法的返回结果是一个列表,其值包含一个元素,而find()方法直接返回结果。CSS选择器BeautifulSoup中常用的css选择器方法有5种,使用的方法是soup.select(),返回类型是列表。按标签名搜索frombs4importBeautifulSoupimportrequestsurl="https://www.baidu.com"content=requests.get(url).contentsoup=BeautifulSoup(content,"lxml")print(soup.select("title"))结果如下图:按CSS类名搜索frombs4importBeautifulSoupimportrequestsurl="https://www.baidu.com"content=requests.get(url).contentsoup=BeautifulSoup(content,"lxml")print(soup.select(".mnav"))结果如下图:searchbyIDfrombs4importBeautifulSoupimportrequestsurl="https://www.baidu.com"content=requests.get(url)。contensoup=BeautifulSoup(content,"lxml")print(soup.select("#lg"))的结果如下图所示:组合搜索组合搜索类似于前端CSS选择器中的组合选择器,组合搜索也可以使用子选择器。frombs4importBeautifulSoupimportrequestsurl="https://www.baidu.com"content=requests.get(url).contentsoup=BeautifulSoup(content,"lxml")print(soup.select('div#lg'))print(soup.select('div>a'))运行结果如下图所示:使用括号通过CSS属性查找属性。注意properties和tags属于同一个节点,所以中间不能加空格,否则匹配不到。frombs4importBeautifulSoupimportrequestsurl="https://www.baidu.com"content=requests.get(url).contentsoup=BeautifulSoup(content,"lxml")print(soup.select('a[class="mnav"]'))不同节点使用属性搜索frombs4importBeautifulSoupimportrequestsurl="https://www.baidu.com"content=requests.get(url).contentsoup=BeautifulSoup(content,"lxml")print(soup.select('spaninput[class="bgs_btn"]'))运行结果如下图所示:修改文档树。frombs4importBeautifulSoupimportrequestssoup=BeautifulSoup('Extremelybold',"lxml")tag=soup.btag.name="newtag"tag['class']='newclass'tag['id']=1print(tag)deltag['class']print(tag)结果如下图:修改标签内容为标签的.string属性赋值相当于替换当前内容的原始内容如果当前标签包含其他标签,为其.string属性赋值将覆盖所有原始内容,包括子标签。frombs4importBeautifulSoupimportrequestsmarkup='我链接到example.com'soup=BeautifulSoup(markup,"lxml")tag=soup.atag.string="新链接文本。"print(tag)操作的结果如下图所示:向标签添加内容Tag.append()方法可以向标签添加内容。frombs4importBeautifulSoupimportrequestssoup=BeautifulSoup("Foo","lxml")soup.a.append("Bar")print(soup)print(soup.a.contents)运行结果如图在下图中注:总结这篇文章有很多内容。BeautifulSoup的大部分方法都已经整理和总结了,但是还不够完整,罗列一些常用的。如果需要完整的,可以查看BeautifulSoup官网的文档。希望对大家有所帮助。,掌握BeautifulSoup一定会给你数据爬取带来便利。本文转载自微信公众号《爱编码社畜》,可关注下方二维码。转载本文请联系Aicode社畜公众号。