python爬虫基础回顾-BeautifulSoup


最简单的爬虫

from urllib.request import urlopen
html = urlopen("http://pythonscraping.com/pages/page1.html") 
print(html.read())

上述代码引入request模块,只导入一个urlopen函数,读取页面然后输出。

神器“BeautifulSoup”

BeautifulSoup库是python爬虫神器之一。通过定位HTML标签来格式化和组织复杂的的网络信息,用简单易用的python对象为我们展示XML结构信息。

安装BeautifulSoup

sudo apt-get install python-bs4

mac 系统

pip install beautifulsoup4

测试是否安装成功

$python
> from bs4 import BeautifulSoup

没有错误导入成功

运行BeautifulSoup

from urllib.request import urlopen
from bs4 import BeautifulSoup
html = urlopen("http://www.pythonscraping.com/pages/page1.html") 
bsObj = BeautifulSoup(html.read())
print(bsObj.h1)

输出 <h1>An Interesting Title</h1>

将html内容传入BeautifulSoup对象,然后通过对象提取h1标签。

复杂的html解析

BeautifulSoup的find()和findAll()函数将是我们最常用的函数。

findAll(tag, attributes, recursive, text, limit, keywords)
find(tag, attributes, recursive, text, keywords)

在大部分时间里我们只会使用前两个参数。
tag参数-传一个或者多个标签名称

.findAll({"h1","h2"})

attrubutes参数-用一个字典封装的若干属性和对应的属性值

.findAll("span",{"class":{"green","red"}})

其他参数请参照文档

BeautifulSoup对象

  • BeautifulSoup对象
  • 标签tag对象
  • NavigableString对象
  • Comment对象

BeautifulSoup导航树

1.处理子标签和其他后代标签

子标签室一个父标签的下一级,后代标签是指一个父标签下面所有级别的标签。一般情况下,beautifulsoup函数总是处理当前标签的后代标签。
bsObj.div.findAll('img’)会找出文档中的第一个div标签,获取这个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)

2.处理兄弟标签

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)

这段代码会打印产品列表里的所有行的产品,第一行表格标题除外。对象不能把自己作为兄弟标签。任何时候你获取一个标签的兄弟标签,都不会包含这个标签本身。其次,这个函数只调用后面的兄弟标签。

3.父标签处理
在特殊情况下你也会用BeautifulSoup 的父标签查找函数,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 这个图片对应商品的价格(这个示例中价格是15.00)。
这是如何实现的呢?下面的图形是我们正在处理的 HTML页面的部分结构,用数字表示步骤的话:

<tr>
--<td>
--<td>
--<td>(3)
    --"15.00" (4)
 --<td>(2)
    --<img src="./img/gifts/img1.jpg"> (1)

(1) 选择图片标签src=”../img/gifts/img1.jpg”;
(2) 选择图片标签的父标签(在示例中是 标签);
(3) 选择 标签的前一个兄弟标签previous_sibling(在示例中是包含美元价格的 标签);
(4) 选择标签中的文字,“$15.00”。

正则表达式

正则表达式和BeautifulSoup结合使用

Lambda表达式

下面的代码就是获取有两个属性的标签:

soup.findAll(lambdatag:len(tag.attrs) == 2)

这行代码会找出下面的标签:

<div class="body" id="content"></div>
<span style="color:red" class="title"></span>

如果你愿意,用lambda表达式选择标签将是正则表达式的完美替代方案。


文章作者: Nczkevin
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Nczkevin !
评论
  目录