当前位置: 首页 > 科技观察

Python爬虫BeautifulSoup

时间:2023-03-12 12:24:24 科技观察

简介BeautifulSoup提供了一些简单的类python函数来处理导航、搜索、修改分析树等功能。它是一个工具箱,通过解析文档为用户提供他们需要抓取的数据。因为简单,不需要太多代码就可以写出一个完整的应用程序。BeautifulSoup自动将输入文档转换为Unicode编码,并将输出文档转换为utf-8编码。你不需要考虑编码方式,除非文档没有指定编码方式,否则BeautifulSoup无法自动识别编码方式。那么,你只需要解释一下原来的编码方式即可。BeautifulSoup已经成为像lxml和html6lib一样出色的python解释器,灵活地为用户提供不同的解析策略或强大的速度。安装pipinstallBeautifulSoup4或easy_installBeautifulSoup4以创建BeautifulSoup对象。首先,您应该从bs4importBeautifulSoup导入BeautifulSoup类库以开始创建对象。在开始之前,为了演示方便,先创建一个html文本,如下:html="""TheDormouse'sstory睡鼠的故事

曾经有三只小姐妹;她们的名字是,Lacie和Tillie;他们住在bottomofawell。

...

"""创建对象:soup=BeautifulSoup(html,'lxml’),这里的lxml就是解析的类库。目前,我认为它是最好的解析器。我一直在用这个。安装方法:pipinstallllxmlTagTag是html中的一个tag,用BeautifulSoup可以解析出Tag的具体内容,具体格式为soup.name,其中name为html下的标签,具体示例如下:printsoup.title#输出title标签下的内容,包括这个标签,这样会输出TheDormouse'sstoryprintsoup.head注意:这里的格式只能获取这些标签中的第一个,获取多个标签的方法后面会提到。Tag有两个重要的属性name和attrs,分别代表名称和属性。介绍如下:name:对于Tag来说,它的名字就是它自己,比如soup.p.name是pattrs是一个字典类型,对应的是attribute-value,比如printsoup.p.attrs,输出是{'class':['title'],'name':'dromouse'},当然你也可以得到具体的值,比如printsoup.p.attrs['class'],输出就是那个[title]是一个列表类型,因为一个属性可能对应多个值,当然你也可以通过get方法获取属性,比如:printsoup.p.get('class')。也可以直接使用printsoup.p['class']getget方法获取标签下的属性值。请注意,这是一个可以在许多场合使用的重要方法。比如你想获取标签下的图片url,那么可以使用soup.img.get('src'),具体分析如下:printsoup.p.get("class")#Getthesrcattributestringunderthe***ptag获取该标签下的文本内容,只有该标签下没有子标签,或者只有一个子标签才能返回内容,否则为将返回无。具体例子如下:printsoup.p.string#上面一段文字p标签没有子标签,所以可以正确返回文字内容printsoup.html.string#这里的结果是None,因为html中有很多子标签,这里get_text()可以获取一个标签中所有的文本内容,包括子节点的内容,这是最常用的文档树搜索方法find_all(name,attrs,recursive,text,**kwargs)find_all用于搜索节点中满足过滤条件的所有节点1.name参数:为Tag的名称,如p,div,title.....soup.find_all("p")找到所有p标签,返回[睡鼠的故事],遍历每个节点即可得到,如下:ps=soup.find_all("p")forpinps:printp.get('class')#获取p标签下的class属性,传入正则表达式:soup.find_all(re.compile(r'^b')查找所有b开头的标签,这里的body和b标签都会被签入incoming类列表:如果传入list参数,BeautifulSoup将返回匹配列表中任意元素的内容。以下代码查找文档中所有的标签和标签soup.find_all(["a","b"])2.KeyWords参考number是传入的属性和对应的属性值,或者其他一些表达式soup.find_all(id='link2'),这个会搜索找到所有id属性为link2的标签传入正则表达式soup.find_all(href=re.compile("elsie")),这会找到所有href属性满足正则表达式的标签,并传入多个值:soup.find_all(id='link2',class_='title'),这将找到同时满足这两个属性的标签。这里的class必须用class_作为参数传入,因为class在python中是关键字。有些属性不能通过上面的方法直接搜索,比如html5中的data-*属性,但是可以通过attrs参数指定一个字典参数来搜索包含特殊属性的标签,如下:#[foo!
]data_soup.find_all(attrs={"data-foo":"value"})#注意这里的atts不仅可以搜索特殊属性,还可以搜索普通属性soup.find_all("p",attrs={'class':'title','id':'value'})#等同于soup.find_all('p',class_='title',id='value')3.text参数:通过text参数可以在文档中搜索字符串内容。它与name参数的可选值相同,text参数接受字符串、正则表达式、列表、Truesoup.find_all(text="Elsie")#[u'Elsie']soup。find_all(text=["Tillie","Elsie","Lacie"])#[u'Elsie',u'Lacie',u'Tillie']soup.find_all(text=re.compile("睡鼠"))[u"TheDormouse'sstory",u"TheDormouse'sstory"]4。limit参数:find_all()方法返回所有的搜索结构,如果文档树很大,搜索会很慢。如果我们不需要所有的结果,我们可以使用limit参数限制返回结果的数量。作用类似于SQL中的limit关键字。当搜索到的结果数达到limit限制时,停止搜索返回结果。文档树中有3个标签符合搜索条件,但是结果只返回了2个,因为我们限制了返回的个数,代码如下:soup.find_all("a",limit=2)#[Elsie,#Lacie]5.递归参数:调用标签当使用find_all()方法时,BeautifulSoup会检索当前标签的所有后代节点。如果只想搜索标签的直接子节点,可以使用参数recursive=Falsefind(name,attrs,recursive,text,**kwargs)和find_all()方法唯一不同的是返回结果find_all()方法的是一个包含一个元素的列表,而find()方法直接返回结果,即直接返回匹配到的元素,不是列表,不遍历,如soup.find("p").get("class")按标签名搜索printsoup.select('title')#[TheDormouse'sstory]printsoup.select('a')#[,Lacie,Tillie]按类名查找printsoup.select('.sister')#[,Lacie,Tillie]按ID名称搜索printsoup.select('#link1')#[]组合搜索学过css的都知道css选择器,比如p#link1是查找p标签下id属性为link1的标签printsoup.select('p#link1')#在p标签中找到id属性为link1的标签#[]printsoup.select("head>title")#直接搜索子标签#[TheDormouse'sstory]搜索属性时也可以添加属性元素,属性需要用方括号括起来,注意属性和标签属于到同一个节点,所以中间不能加空格,否则匹配不上printsoup.select('a[class="sister"]')#[,拉西,Tillie]printsoup.select('a[href="http://example.com/elsie"]')#[]同样的,属性还是可以结合上面的搜索方式,在同一个里不用空格隔开node,同一个Node不带空格,代码如下:printsoup.select('pa[href="http://example.com/elsie"]')#[]上面select方法返回的结果都是列表形式,可以遍历输出form,然后使用get_text()方法获取其内容soup=BeautifulSoup(html,'lxml')printtype(soup.select('title'))printsoup.select('title')[0].get_text()fortitleinsoup.select('title'):printtitle.get_text()