*文章说明这个学习资料是Ryan Mitchel的著作<Web Scraping with Python: Collecting Data from the Modern Web>我算是一步一步跟着一起去学习。分享自及遇到的问题。总结
*环境说明我使用的是python3.5+python2.7共存。
网络爬虫可以通过 class 属性的值,轻松地区分出两种不同的标签。例如,它们可以用BeautifulSoup 抓取网页上所有的红色文字,而绿色文字一个都不抓。
下面让我们创建一个网络爬虫来抓取 http://www.pythonscraping.com/pages/warandpeace.html这个网页
按下F12进入开发者模式
可以看到在这个页面里,小说人物的对话内容都是红色的,人物名称都是绿色的。
<span class="red"><span class="green">这是两个css样式标签,那么接下来我们通过css样式标签进行网站信息爬取。
首先我们爬取所有的名字
from urllib.request import urlopen
from bs4 import BeautifulSoup
import html5lib
html = urlopen("http://www.pythonscraping.com/pages/warandpeace.html")
bsObj = BeautifulSoup(html.read(), "html.parser")
nameList = bsObj.findAll("span", {"class": "green"})
for name in nameList:
print(name.get_text())
#.get_text() 会把你正在处理的 HTML 文档中所有的标签都清除,然后返回一个只包含文字的字符串。
下面是我们的爬取结果
之后我们要去爬取小说的对话内容代码相同我们只需要修改findall函数的参数为findAll("span", {"class":"red"})即可
from urllib.request import urlopen
from bs4 import BeautifulSoup
import html5lib
html = urlopen("http://www.pythonscraping.com/pages/warandpeace.html")
bsObj = BeautifulSoup(html.read(), "html.parser")
nameList = bsObj.findAll("span", {"class": "red"})
for name in nameList:
print(name.get_text())
运行结果如下
***简单的说明一下:爬取是如果提示远程服务器拒绝访问一类的报错那么可能是网络原因,再次运行即可***
这里还要介绍下find()和findall()
find()找到第一个满足条件的标签就返回,findAll()找到所有满足条件的标签返回。
看一下两个函数的参数,findAll多了一个limit参数。 #参数不是每次用的时候需要把所有参数都要写出来
findAll(tag,atributes,recursive,text,limit,keywords)# recursive 递归的,循环的
find(tag,atributes,recursive,text,keywords)
实例中多用findAll()函数,因为find()函数只返回一个,没有代表性。
①参数tag,可以使用参数tag表明需要查找的标签类型,tag可以是多个:
.findAll({'h1'}) #返回h1标签列表
.findAll({'h1','h2','h3'}) #返回h1-h3标题标签列表
.findAll({'h1','h2','h3','h4','h5','h6','h7'}) #返回所有标题标签的列表
②参数attribute,使用标签内的若干属性对应的属性值进行标签查找,属性值可以是多个
.findAll('span',{'class':{'green','red'}}) #返回class属性为red和green的span标签列表
③参数recursive,是否使用递归方法遍历每一个子标签,默认是开启,True。如果设置为False,findAll()只查找文档的一级标签。一般使用中,不用去动这个参数
④参数text,根据标签的文本内容去查找标签列表,通常配合正则表达式使用
nameList = bsObj.findAll(text='the prince') #匹配所有标签文本内容为‘the prince’的标签列表
nameList = bsObj.findAll(text=re.compile('the*')) #匹配所有标签文本内容为‘the’开头的标签列表,使用了正则表达式re,正则表达式在此文中不做讲解
⑤参数limit,范围限制参数,显然只能用于findAll()函数。就是限定返回的个数,比如要抽取多少个标签信息做样本之类的
⑥参数keyword,标签内指定属性的标签列表#与attribute参数相似,有一个例外就是用class属性查找标签的时候,直接findAll(class=‘green’)会报错,因为class是保留字
bsObj.findAll(id='text')
bsObj.findAll(class='text') #会报错
bsObj.findAll(class_='text')解决方案