当咱们想要从复杂的网络信息中抽取出咱们须要的信息时,不假思索的写出层层抽取的代码是很是不理智的。这样的代码又臭又长,难以阅读,且容易失效。正确的方法是三思然后行,使用正确的技巧方法写出简洁,易懂,扩展性强的代码。 重要的事情说三遍:三思然后行,三思然后行,三思然后行html
网页的class属性和id属性是很是丰富的,咱们可使用这些属性来抽取信息: 例子:python
from urllib.request import urlopen from bs4 import BeautifulSoup html = urlopen("http://pythonscraping.com/pages/warandpeace.html") #网页html代码赋给变量bs0bj bs0bj = BeautifulSoup(html) #返回一个含有class=green属性的列表 namelist = bs0bj.findAll("span",{"class":"green"}) #遍历输出列表中不含标签的文字。 for name in namelist: print(name.get_text())
.get_text():把正在处理的html文档中的全部标签都清除,返回一个只包含文字的字符串,通常状况下因尽量保留标签,在最后状况下使用get_text()。正则表达式
find()和finaall()这两个函数是很是经常使用的,咱们能够用它们找到须要的标签或标签组。 函数的格式定义以下:api
findAll(tag, attributes, recursive, text, limit, keywords) find(tag, attributes, recursive, text, keywords)
整个html页面能够简化为一棵树,以下所示:网络
1.处理子标签和后代标签:函数
通常状况下,beautifulsoup老是处理当前标签下的后代标签,如bs0bj.body.h1是处理当前body标签下的第一个h1标签。bs0bj.body.finaAll("img")是找到第一div标签下的索引img列表。学习
若是只想要找到子标签,可使用.children标签。测试
from urllib.request import urlopen from bs4 import BeautifulSoup html = urlopen("http://www.pythonscraping.com/pages/page3.html") bsObj = BeautifulSoup(html) for child in bsObj.find("table",{"id":"giftList"}).children: print(child)
上面的代码会打印giftlist表格中的索引产品的数据行。this
使用descendants()标签能够输出全部的后代标签。url
2.兄弟标签: 使用next_siblings()函数能够处理兄弟标签。
from urllib.request import urlopen from bs4 import BeautifulSoup html = urlopen("http://www.pythonscraping.com/pages/page3.html") bsObj = BeautifulSoup(html) for sibling in bsObj.find("table",{"id":"giftList"}).tr.next_siblings: print(sibling)
使用兄弟标签会跳过标签自身,由于自身不能看成本身的兄弟,同时兄弟标签只能查找后面的标签,不能查找自身以及前面的兄弟标签。
与next_siblings()相似,previous_siblings()函数是查找前面的兄弟节点。
同时还有next_siblings()和previous_siblings()函数,它们的做业是返回单个标签。
3.父标签
使用parent和parents标签能够查找给定标签的父标签或父标签列表。
from urllib.request import urlopen from bs4 import BeautifulSoup html = urlopen("http://www.pythonscraping.com/pages/page3.html") bsObj = BeautifulSoup(html) print(bsObj.find("img",{"src":"../img/gifts/img1.jpg" }).parent.previous_sibling.get_text())
上面代码的意思是找到给定标签的父标签的前一个兄弟标签中的文字。
正则表达式是很是丰富的,可是上手很简单。能够本身搜索一些教程学习。 正则测试:http://www.regexpal.com/
正则表达式是很是有用的,举个例子,加入你想要抓取索引的img图片,使用finaall()获得的结果可能会出乎意料,多了许多隐藏的图片或不相关的图片,此时可使用正则表达式。咱们发现想要获取的图片源代码格式以下:
<img src="../img/gifts/img3.jpg">
这样咱们能够直接经过文件路径来查找信息,
from urllib.request import urlopenfrom bs4 import BeautifulSoupimport re html = urlopen("http://www.pythonscraping.com/pages/page3.html") bsObj = BeautifulSoup(html) images = bsObj.findAll("img", {"src":re.compile("\.\.\/img\/gifts/img.*\.jpg")}) for image in images: print(image["src"])
上面的例子使用了正则表达式匹配了以../img/gifts/img开头,以.jpg结尾的图片。结果以下:
../img/gifts/img1.jpg ../img/gifts/img2.jpg ../img/gifts/img3.jpg ../img/gifts/img4.jpg ../img/gifts/img6.jpg
对于一个标签对象,可使用下面代码得到它的所有属性:
myTag.attrs
得到的属性存在一个字典中,能够取出某一个属性
myTag.attrs["href"]