python——网络数据采集--复杂HTML解析

一、使用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"就是获取图片路径的正则表达式

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值