一、使用BeautifulSoup和网页标签抓取内容
1.打开网页:http://www.pythonscraping.com/pages/warandpeace.html 2.按F12查看网页结构
3.可以看到有这样两个标签:
<span class="green"></span>
<span class="red"></span>
分别代表绿字和红字
我们访问绿字,绿字包含人名
4.打开pycharm,新建文件
5.输入以下代码:
from urllib.request import urlopen
from bs4 import BeautifulSoup
html=urlopen("http://www.pythonscraping.com/pages/warandpeace.html")
bsobj=BeautifulSoup(html)
namelist=bsobj.findAll("span",{"class":"green"}) #bsobj.findAll()可以获取页面中所有指定的标签
for name in namelist:
print(name.get.text()) #get.text可以将HTML文档中的所有标签清除,返回一个只包含文字的字符串
运行代码后,可以看到人名出现在屏幕上
二、BeautifulSoup的find()和findAll()
findAll()括号内的元素可以是:标签、属性、递归、文本、范围限制、关键字
find()括号内的的元素可以是:标签、属性、递归、文本、关键字
以下是每种元素的解释:
1)标签:(tag) 可以传入一个标签的名称或多个标签组成的Python列表作为标签
例:.findAll({“h1”,“h2”,“h3”,“h4”,“h5”,“h6”,“h7”})可以返回一个包含HTML文档中所有标题标签的列表。
2)属性:(attributes) 是一个用python字典封装一个标签的若干属性和对应的属性值。
例:。findAll(“span”,{“class”:{“green”,“red”}})会返回HTML文档里红色和绿色两种span标签
3)文本:(text) 用标签的文本内容匹配,不用标签的属性
例:若想查找前面网页中包含“the prince”内容的标签数量,可以把之前的findAll方法换成如下代码:
namelist=bsobj.findAll(text="the prince")
print(len(namelist))
4)递归:(recursive) 递归参数是一个布尔变量。若递归设置为True,findAll就会根据你的要求去查找标签参数的所有子标签,以及子标签的子标签,若设置为False,findAll就只找文档的一级标签。
5)范围限制参数:(limit) 只用于findAll方法,若只对网页中获取的前几项结果感兴趣,就可以设置,但这前几项结果是按照网页上的顺序排列的,不一定是想要的结果
6)关键字 (keyword) 可以选择那些具有指定属性的标签
例:
allText=bsobj.findAll(id="text")
print(allText[0].get_text())
三、其他BeautifulSoup对象
1)BeautifulSoup对象:
前面代码中的bsobj
2)标签Tag对象
BeautifulSoup对象通过find和findAll,或者直接调用子标签获取的一列对象或单一对象,就像:bsobj.div.h1
这个库中的另外两种对象:
1)NavigableString对象
用来表示标签中的文字,不是标签
2)Comment对象
用来查找HTML文档的注释标签,<! - - 像这样 - - >
四、导航树
导航树的作用:通过标签在文档中的位置来查找标签
http://www.pythonscraping.com/pages/page3.html 网站的树的结构:
html
——body
——div.wrapper
——h1
——div.content
——table#giftList
——tr
——th
——th
——th
——th
——tr.gift#gift1
——td
——td
——span.excitingNote
——td
——td
——img
——其他表格行
——div.footer
1)处理子标签和其他后代标签
子标签是父标签的下一级,后代标签是指一个父标签下面所有级别的标签。
例如:上面tr标签是table的子标签,而tr,th,td,img和span标签都是table标签的后代标签
所有的子标签都是后代标签,但不是所有后代标签都是子标签
若想找出子标签,可以用.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表格中所有产品的数据行。
2)处理兄弟标签
BeautifulSoup的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()函数只能调用后面的兄弟标签,例如:如果我们选择一组标签中位于中间位置的表签,用这个函数只能调用它后面的标签
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())
以上代码会打印…/img/gifts/img1.jpg这个图片对应商品的价格
五、正则表达式
正则表达式可以识别正则字符串,可以这样定义:
如果给我的字符串符合规则,我就返回它
一个例子:
字母"a"至少出现一次,后面跟着字母"b"重复5次,后面再跟着字母"c"重复任意偶数次,最后一位是字母"d",也可以没有
以上规则的正则表达式如下:
aabbbbb(cc)(d|)
解释:
1)aa*
a后面跟着的a*表示重复任意次a,包括0次
2)bbbbb
b重复5次
3)(cc)*
表示任意偶数个字符都可以编组,有任意两个c
4)(d|)
竖线表示”这个或那个“,(d|)表示最后一位是字母"d",也可以没有
要多写正则表达式才能熟练掌握,我们可以在http://regexpal.com/这类网站上去尝试写正则表达式。
更多的正则表达式内容可以自己百度一下,百度上的内容非常多,我就不多做介绍了
六、正则表达式和BeautifulSoup
在抓取网页时Beautiful总是与正则表达式配合使用
例:抓取网页"http://www.pythonscraping.com/pages/page3.html"
所有图片的链接,过滤掉空白图片和图片标签:
from urllib.request import urlopen
from bs4 import BeautifulSoup
import 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"就是获取图片路径的正则表达式